diff options
255 files changed, 2897 insertions, 3049 deletions
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java index 03c9d43d3258..adcd5710ef19 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java @@ -158,14 +158,6 @@ public class ExpensiveObjectsPerfTest { } @Test - public void timeNewSimpleDateFormat() { - BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); - while (state.keepRunning()) { - new SimpleDateFormat(); - } - } - - @Test public void timeClonedSimpleDateFormat() { SimpleDateFormat sdf = new SimpleDateFormat(); BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/BroadcastWaiter.java b/apct-tests/perftests/multiuser/src/android/multiuser/BroadcastWaiter.java index 7ed97fbb440e..dcabca476925 100644 --- a/apct-tests/perftests/multiuser/src/android/multiuser/BroadcastWaiter.java +++ b/apct-tests/perftests/multiuser/src/android/multiuser/BroadcastWaiter.java @@ -23,9 +23,12 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.os.SystemClock; import android.text.TextUtils; import android.util.Log; +import com.android.internal.util.FunctionalUtils; + import java.io.Closeable; import java.util.ArrayList; import java.util.Arrays; @@ -72,7 +75,8 @@ public class BroadcastWaiter implements Closeable { @Override public void onReceive(Context context, Intent intent) { if (action.equals(intent.getAction())) { - final int userId = getSendingUserId(); + final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, + getSendingUserId()); final String data = intent.getDataString(); Log.d(mTag, "Received " + action + " for user " + userId + (!TextUtils.isEmpty(data) ? " with " + data : "")); @@ -95,7 +99,7 @@ public class BroadcastWaiter implements Closeable { return mActionReceivedForUser.contains(action + userId); } - public boolean waitActionForUser(String action, int userId) { + private boolean waitActionForUser(String action, int userId) { Log.d(mTag, "#waitActionForUser(action: " + action + ", userId: " + userId + ")"); if (!mActions.contains(action)) { @@ -103,18 +107,40 @@ public class BroadcastWaiter implements Closeable { return false; } + final long startTime = SystemClock.elapsedRealtime(); try { - if (!getSemaphore(action, userId).tryAcquire(1, mTimeoutInSecond, SECONDS)) { - Log.e(mTag, action + " broadcast wasn't received for user " + userId); + final boolean doneBeforeTimeout = getSemaphore(action, userId) + .tryAcquire(1, mTimeoutInSecond, SECONDS); + if (!doneBeforeTimeout) { + Log.e(mTag, action + " broadcast wasn't received for user " + userId + + " in " + mTimeoutInSecond + " seconds"); return false; } } catch (InterruptedException e) { Log.e(mTag, "Interrupted while waiting " + action + " for user " + userId); return false; } + final long elapsedTime = SystemClock.elapsedRealtime() - startTime; + Log.d(mTag, action + " broadcast received for user " + userId + + " in " + elapsedTime + " ms"); return true; } + public String runThenWaitForBroadcasts(int userId, FunctionalUtils.ThrowingRunnable runnable, + String... actions) { + for (String action : actions) { + mActionReceivedForUser.remove(action + userId); + getSemaphore(action, userId).drainPermits(); + } + runnable.run(); + for (String action : actions) { + if (!waitActionForUser(action, userId)) { + return action; + } + } + return null; + } + public boolean waitActionForUserIfNotReceivedYet(String action, int userId) { return hasActionBeenReceivedForUser(action, userId) || waitActionForUser(action, userId); diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java index a44d93972ae1..734545376279 100644 --- a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java +++ b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java @@ -23,14 +23,12 @@ import android.app.ActivityTaskManager; import android.app.AppGlobals; import android.app.IActivityManager; import android.app.IStopUserCallback; -import android.app.UserSwitchObserver; import android.app.WaitResult; import android.content.BroadcastReceiver; import android.content.Context; import android.content.IIntentReceiver; import android.content.IIntentSender; import android.content.Intent; -import android.content.IntentFilter; import android.content.IntentSender; import android.content.pm.IPackageInstaller; import android.content.pm.PackageManager; @@ -51,6 +49,8 @@ import androidx.test.InstrumentationRegistry; import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; +import com.android.internal.util.FunctionalUtils; + import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -115,6 +115,7 @@ public class UserLifecycleTests { private ArrayList<Integer> mUsersToRemove; private boolean mHasManagedUserFeature; private BroadcastWaiter mBroadcastWaiter; + private UserSwitchWaiter mUserSwitchWaiter; private final BenchmarkRunner mRunner = new BenchmarkRunner(); @Rule @@ -132,7 +133,9 @@ public class UserLifecycleTests { mBroadcastWaiter = new BroadcastWaiter(context, TAG, TIMEOUT_IN_SECOND, Intent.ACTION_USER_STARTED, Intent.ACTION_MEDIA_MOUNTED, - Intent.ACTION_USER_UNLOCKED); + Intent.ACTION_USER_UNLOCKED, + Intent.ACTION_USER_STOPPED); + mUserSwitchWaiter = new UserSwitchWaiter(TAG, TIMEOUT_IN_SECOND); removeAnyPreviousTestUsers(); if (mAm.getCurrentUser() != UserHandle.USER_SYSTEM) { Log.w(TAG, "WARNING: Tests are being run from user " + mAm.getCurrentUser() @@ -175,8 +178,9 @@ public class UserLifecycleTests { // Don't use this.startUserInBackgroundAndWaitForUnlock() since only waiting until // ACTION_USER_STARTED. - mIam.startUserInBackground(userId); - waitForBroadcast(Intent.ACTION_USER_STARTED, userId); + runThenWaitForBroadcasts(userId, () -> { + mIam.startUserInBackground(userId); + }, Intent.ACTION_USER_STARTED); mRunner.pauseTiming(); Log.i(TAG, "Stopping timer"); @@ -197,8 +201,9 @@ public class UserLifecycleTests { mRunner.resumeTiming(); Log.i(TAG, "Starting timer"); - mIam.startUserInBackground(userId); - waitForBroadcast(Intent.ACTION_USER_STARTED, userId); + runThenWaitForBroadcasts(userId, () -> { + mIam.startUserInBackground(userId); + }, Intent.ACTION_USER_STARTED); mRunner.pauseTiming(); Log.i(TAG, "Stopping timer"); @@ -259,8 +264,9 @@ public class UserLifecycleTests { mRunner.resumeTiming(); Log.i(TAG, "Starting timer"); - mAm.switchUser(testUser); - waitForBroadcast(Intent.ACTION_USER_UNLOCKED, testUser); + runThenWaitForBroadcasts(testUser, () -> { + mAm.switchUser(testUser); + }, Intent.ACTION_USER_UNLOCKED); mRunner.pauseTiming(); Log.i(TAG, "Stopping timer"); @@ -296,10 +302,10 @@ public class UserLifecycleTests { while (mRunner.keepRunning()) { mRunner.pauseTiming(); final int userId = createUserNoFlags(); - mIam.startUserInBackground(userId); - waitForBroadcast(Intent.ACTION_USER_STARTED, userId); - waitForBroadcast(Intent.ACTION_MEDIA_MOUNTED, userId); + runThenWaitForBroadcasts(userId, ()-> { + mIam.startUserInBackground(userId); + }, Intent.ACTION_USER_STARTED, Intent.ACTION_MEDIA_MOUNTED); mRunner.resumeTiming(); Log.i(TAG, "Starting timer"); @@ -320,13 +326,12 @@ public class UserLifecycleTests { mRunner.pauseTiming(); final int startUser = mAm.getCurrentUser(); final int userId = createUserNoFlags(); - final CountDownLatch latch = new CountDownLatch(1); - registerUserSwitchObserver(null, latch, userId); - mRunner.resumeTiming(); - Log.i(TAG, "Starting timer"); - mAm.switchUser(userId); - waitForLatch("Failed to achieve onLockedBootComplete for user " + userId, latch); + mUserSwitchWaiter.runThenWaitUntilBootCompleted(userId, () -> { + mRunner.resumeTiming(); + Log.i(TAG, "Starting timer"); + mAm.switchUser(userId); + }, () -> fail("Failed to achieve onLockedBootComplete for user " + userId)); mRunner.pauseTiming(); Log.i(TAG, "Stopping timer"); @@ -343,34 +348,22 @@ public class UserLifecycleTests { mRunner.pauseTiming(); final int startUser = mAm.getCurrentUser(); final int userId = createUserWithFlags(UserInfo.FLAG_EPHEMERAL | UserInfo.FLAG_DEMO); - switchUser(userId); - waitForBroadcast(Intent.ACTION_MEDIA_MOUNTED, userId); - - final CountDownLatch latch = new CountDownLatch(1); - InstrumentationRegistry.getContext().registerReceiver(new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (Intent.ACTION_USER_STOPPED.equals(intent.getAction()) && intent.getIntExtra( - Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL) == userId) { - latch.countDown(); - } - } - }, new IntentFilter(Intent.ACTION_USER_STOPPED)); - final CountDownLatch switchLatch = new CountDownLatch(1); - registerUserSwitchObserver(switchLatch, null, startUser); - mRunner.resumeTiming(); - Log.i(TAG, "Starting timer"); + runThenWaitForBroadcasts(userId, () -> { + switchUser(userId); + }, Intent.ACTION_MEDIA_MOUNTED); - mAm.switchUser(startUser); - waitForLatch("Failed to achieve ACTION_USER_STOPPED for user " + userId, latch); + mUserSwitchWaiter.runThenWaitUntilSwitchCompleted(startUser, () -> { + mRunner.resumeTiming(); + Log.i(TAG, "Starting timer"); + + runThenWaitForBroadcasts(userId, () -> { + mAm.switchUser(startUser); + }, Intent.ACTION_USER_STOPPED); + + mRunner.pauseTiming(); + Log.i(TAG, "Stopping timer"); + }, null); - mRunner.pauseTiming(); - Log.i(TAG, "Stopping timer"); - try { - switchLatch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS); - } catch (InterruptedException e) { - Log.e(TAG, "Thread interrupted unexpectedly while waiting for switch.", e); - } removeUser(userId); mRunner.resumeTimingForNextIteration(); } @@ -547,8 +540,9 @@ public class UserLifecycleTests { while (mRunner.keepRunning()) { mRunner.pauseTiming(); final int userId = createManagedProfile(); - startUserInBackgroundAndWaitForUnlock(userId); - waitForBroadcast(Intent.ACTION_MEDIA_MOUNTED, userId); + runThenWaitForBroadcasts(userId, () -> { + startUserInBackgroundAndWaitForUnlock(userId); + }, Intent.ACTION_MEDIA_MOUNTED); mRunner.resumeTiming(); Log.i(TAG, "Starting timer"); @@ -667,15 +661,11 @@ public class UserLifecycleTests { * If lack of success should fail the test, use {@link #switchUser(int)} instead. */ private boolean switchUserNoCheck(int userId) throws RemoteException { - final CountDownLatch latch = new CountDownLatch(1); - registerUserSwitchObserver(latch, null, userId); - mAm.switchUser(userId); - try { - return latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS); - } catch (InterruptedException e) { - Log.e(TAG, "Thread interrupted unexpectedly.", e); - return false; - } + final boolean[] success = {true}; + mUserSwitchWaiter.runThenWaitUntilSwitchCompleted(userId, () -> { + mAm.switchUser(userId); + }, () -> success[0] = false); + return success[0]; } private void stopUser(int userId, boolean force) throws RemoteException { @@ -704,9 +694,9 @@ public class UserLifecycleTests { final int origUser = mAm.getCurrentUser(); // First, create and switch to testUser, waiting for its ACTION_USER_UNLOCKED final int testUser = createUserNoFlags(); - mAm.switchUser(testUser); - waitForBroadcast(Intent.ACTION_USER_UNLOCKED, testUser); - waitForBroadcast(Intent.ACTION_MEDIA_MOUNTED, testUser); + runThenWaitForBroadcasts(testUser, () -> { + mAm.switchUser(testUser); + }, Intent.ACTION_USER_UNLOCKED, Intent.ACTION_MEDIA_MOUNTED); // Second, switch back to origUser, waiting merely for switchUser() to finish switchUser(origUser); @@ -756,26 +746,6 @@ public class UserLifecycleTests { result.result == ActivityManager.START_SUCCESS); } - private void registerUserSwitchObserver(final CountDownLatch switchLatch, - final CountDownLatch bootCompleteLatch, final int userId) throws RemoteException { - ActivityManager.getService().registerUserSwitchObserver( - new UserSwitchObserver() { - @Override - public void onUserSwitchComplete(int newUserId) throws RemoteException { - if (switchLatch != null && userId == newUserId) { - switchLatch.countDown(); - } - } - - @Override - public void onLockedBootComplete(int newUserId) { - if (bootCompleteLatch != null && userId == newUserId) { - bootCompleteLatch.countDown(); - } - } - }, TAG); - } - private class ProgressWaiter extends IProgressListener.Stub { private final CountDownLatch mFinishedLatch = new CountDownLatch(1); @@ -803,12 +773,21 @@ public class UserLifecycleTests { /** * Waits TIMEOUT_IN_SECOND for the broadcast to be received, otherwise declares the given error. * It only works for the broadcasts provided in {@link #mBroadcastWaiter}'s instantiation above. - * @param action action of the broadcast, i.e. {@link Intent#ACTION_USER_STARTED} - * @param userId sendingUserId of the broadcast. See {@link BroadcastReceiver#getSendingUserId} + * @param userId userId associated with the broadcast. It is {@link Intent#EXTRA_USER_HANDLE} + * or in case that is null, then it is {@link BroadcastReceiver#getSendingUserId}. + * @param runnable function to be run after clearing any possible previously received broadcasts + * and before waiting for the new broadcasts. This function should typically do + * something to trigger broadcasts to be sent. Like starting or stopping a user. + * @param actions actions of the broadcasts, i.e. {@link Intent#ACTION_USER_STARTED}. + * If multiple actions are provided, they will be waited in given order. */ - private void waitForBroadcast(String action, int userId) { - attestTrue("Failed to achieve " + action + " for user " + userId, - mBroadcastWaiter.waitActionForUser(action, userId)); + private void runThenWaitForBroadcasts(int userId, FunctionalUtils.ThrowingRunnable runnable, + String... actions) { + final String unreceivedAction = + mBroadcastWaiter.runThenWaitForBroadcasts(userId, runnable, actions); + + attestTrue("Failed to achieve " + unreceivedAction + " for user " + userId, + unreceivedAction == null); } /** Waits TIMEOUT_IN_SECOND for the latch to complete, otherwise declares the given error. */ @@ -874,10 +853,14 @@ public class UserLifecycleTests { } } + private void fail(@NonNull String message) { + Log.e(TAG, "Test failed on iteration #" + mRunner.getIteration() + ": " + message); + mRunner.markAsFailed(new AssertionError(message)); + } + private void attestTrue(@NonNull String message, boolean assertion) { if (!assertion) { - Log.e(TAG, "Test failed on iteration #" + mRunner.getIteration() + ": " + message); - mRunner.markAsFailed(new AssertionError(message)); + fail(message); } } diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/UserSwitchWaiter.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserSwitchWaiter.java new file mode 100644 index 000000000000..228d14c3a05b --- /dev/null +++ b/apct-tests/perftests/multiuser/src/android/multiuser/UserSwitchWaiter.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2022 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.multiuser; + +import android.app.ActivityManager; +import android.app.UserSwitchObserver; +import android.os.RemoteException; +import android.util.Log; + +import com.android.internal.util.FunctionalUtils; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +public class UserSwitchWaiter { + + private final String mTag; + private final int mTimeoutInSecond; + + public UserSwitchWaiter(String tag, int timeoutInSecond) { + mTag = tag; + mTimeoutInSecond = timeoutInSecond; + } + + public void runThenWaitUntilSwitchCompleted(int userId, + FunctionalUtils.ThrowingRunnable runnable, Runnable onFail) throws RemoteException { + final CountDownLatch latch = new CountDownLatch(1); + ActivityManager.getService().registerUserSwitchObserver( + new UserSwitchObserver() { + @Override + public void onUserSwitchComplete(int newUserId) throws RemoteException { + if (userId == newUserId) { + latch.countDown(); + } + } + }, mTag); + runnable.run(); + waitForLatch(latch, onFail); + } + + public void runThenWaitUntilBootCompleted(int userId, + FunctionalUtils.ThrowingRunnable runnable, Runnable onFail) throws RemoteException { + final CountDownLatch latch = new CountDownLatch(1); + ActivityManager.getService().registerUserSwitchObserver( + new UserSwitchObserver() { + @Override + public void onLockedBootComplete(int newUserId) { + if (userId == newUserId) { + latch.countDown(); + } + } + }, mTag); + runnable.run(); + waitForLatch(latch, onFail); + } + + private void waitForLatch(CountDownLatch latch, Runnable onFail) { + boolean success = false; + try { + success = latch.await(mTimeoutInSecond, TimeUnit.SECONDS); + } catch (InterruptedException e) { + Log.e(mTag, "Thread interrupted unexpectedly.", e); + } + if (!success && onFail != null) { + onFail.run(); + } + } +} diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java index c17fbf19516b..90b78288d0c6 100644 --- a/core/java/android/accessibilityservice/AccessibilityService.java +++ b/core/java/android/accessibilityservice/AccessibilityService.java @@ -2590,9 +2590,9 @@ public abstract class AccessibilityService extends Service { return; } final HardwareBuffer hardwareBuffer = - result.getParcelable(KEY_ACCESSIBILITY_SCREENSHOT_HARDWAREBUFFER); + result.getParcelable(KEY_ACCESSIBILITY_SCREENSHOT_HARDWAREBUFFER, android.hardware.HardwareBuffer.class); final ParcelableColorSpace colorSpace = - result.getParcelable(KEY_ACCESSIBILITY_SCREENSHOT_COLORSPACE); + result.getParcelable(KEY_ACCESSIBILITY_SCREENSHOT_COLORSPACE, android.graphics.ParcelableColorSpace.class); final ScreenshotResult screenshot = new ScreenshotResult(hardwareBuffer, colorSpace.getColorSpace(), result.getLong(KEY_ACCESSIBILITY_SCREENSHOT_TIMESTAMP)); diff --git a/core/java/android/accounts/AbstractAccountAuthenticator.java b/core/java/android/accounts/AbstractAccountAuthenticator.java index 3807b503ce70..a3a361501b1c 100644 --- a/core/java/android/accounts/AbstractAccountAuthenticator.java +++ b/core/java/android/accounts/AbstractAccountAuthenticator.java @@ -938,7 +938,7 @@ public abstract class AbstractAccountAuthenticator { String authTokenType = sessionBundle.getString(KEY_AUTH_TOKEN_TYPE); Bundle options = sessionBundle.getBundle(KEY_OPTIONS); String[] requiredFeatures = sessionBundle.getStringArray(KEY_REQUIRED_FEATURES); - Account account = sessionBundle.getParcelable(KEY_ACCOUNT); + Account account = sessionBundle.getParcelable(KEY_ACCOUNT, android.accounts.Account.class); boolean containsKeyAccount = sessionBundle.containsKey(KEY_ACCOUNT); // Actual options passed to add account or update credentials flow. diff --git a/core/java/android/accounts/AccountAuthenticatorActivity.java b/core/java/android/accounts/AccountAuthenticatorActivity.java index 65ba35ff9e8d..5f620f356e7a 100644 --- a/core/java/android/accounts/AccountAuthenticatorActivity.java +++ b/core/java/android/accounts/AccountAuthenticatorActivity.java @@ -60,7 +60,7 @@ public class AccountAuthenticatorActivity extends Activity { super.onCreate(icicle); mAccountAuthenticatorResponse = - getIntent().getParcelableExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE); + getIntent().getParcelableExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, android.accounts.AccountAuthenticatorResponse.class); if (mAccountAuthenticatorResponse != null) { mAccountAuthenticatorResponse.onRequestContinued(); diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java index fa9de6e27282..a573776e8670 100644 --- a/core/java/android/accounts/AccountManager.java +++ b/core/java/android/accounts/AccountManager.java @@ -2450,7 +2450,7 @@ public class AccountManager { onError(ERROR_CODE_INVALID_RESPONSE, "null bundle returned"); return; } - Intent intent = bundle.getParcelable(KEY_INTENT); + Intent intent = bundle.getParcelable(KEY_INTENT, android.content.Intent.class); if (intent != null && mActivity != null) { // since the user provided an Activity we will silently start intents // that we see diff --git a/core/java/android/accounts/ChooseAccountActivity.java b/core/java/android/accounts/ChooseAccountActivity.java index 6c8744f28864..20142a6d90e1 100644 --- a/core/java/android/accounts/ChooseAccountActivity.java +++ b/core/java/android/accounts/ChooseAccountActivity.java @@ -62,7 +62,7 @@ public class ChooseAccountActivity extends Activity { .SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); mAccounts = getIntent().getParcelableArrayExtra(AccountManager.KEY_ACCOUNTS); mAccountManagerResponse = - getIntent().getParcelableExtra(AccountManager.KEY_ACCOUNT_MANAGER_RESPONSE); + getIntent().getParcelableExtra(AccountManager.KEY_ACCOUNT_MANAGER_RESPONSE, android.accounts.AccountManagerResponse.class); // KEY_ACCOUNTS is a required parameter if (mAccounts == null) { diff --git a/core/java/android/accounts/ChooseTypeAndAccountActivity.java b/core/java/android/accounts/ChooseTypeAndAccountActivity.java index f623295dee3e..4d4a4d78ac81 100644 --- a/core/java/android/accounts/ChooseTypeAndAccountActivity.java +++ b/core/java/android/accounts/ChooseTypeAndAccountActivity.java @@ -186,7 +186,7 @@ public class ChooseTypeAndAccountActivity extends Activity mExistingAccounts = null; // If the selected account as specified in the intent matches one in the list we will // show is as pre-selected. - Account selectedAccount = (Account) intent.getParcelableExtra(EXTRA_SELECTED_ACCOUNT); + Account selectedAccount = (Account) intent.getParcelableExtra(EXTRA_SELECTED_ACCOUNT, android.accounts.Account.class); if (selectedAccount != null) { mSelectedAccountName = selectedAccount.name; } @@ -396,7 +396,7 @@ public class ChooseTypeAndAccountActivity extends Activity try { final Bundle accountManagerResult = accountManagerFuture.getResult(); final Intent intent = (Intent)accountManagerResult.getParcelable( - AccountManager.KEY_INTENT); + AccountManager.KEY_INTENT, android.content.Intent.class); if (intent != null) { mPendingRequest = REQUEST_ADD_ACCOUNT; mExistingAccounts = AccountManager.get(this).getAccountsForPackage(mCallingPackage, diff --git a/core/java/android/accounts/GrantCredentialsPermissionActivity.java b/core/java/android/accounts/GrantCredentialsPermissionActivity.java index 74dae0ecceb7..a89fae72d4ab 100644 --- a/core/java/android/accounts/GrantCredentialsPermissionActivity.java +++ b/core/java/android/accounts/GrantCredentialsPermissionActivity.java @@ -68,7 +68,7 @@ public class GrantCredentialsPermissionActivity extends Activity implements View } // Grant 'account'/'type' to mUID - mAccount = extras.getParcelable(EXTRAS_ACCOUNT); + mAccount = extras.getParcelable(EXTRAS_ACCOUNT, android.accounts.Account.class); mAuthTokenType = extras.getString(EXTRAS_AUTH_TOKEN_TYPE); mUid = extras.getInt(EXTRAS_REQUESTING_UID); final PackageManager pm = getPackageManager(); @@ -199,7 +199,7 @@ public class GrantCredentialsPermissionActivity extends Activity implements View */ public void finish() { Intent intent = getIntent(); - AccountAuthenticatorResponse response = intent.getParcelableExtra(EXTRAS_RESPONSE); + AccountAuthenticatorResponse response = intent.getParcelableExtra(EXTRAS_RESPONSE, android.accounts.AccountAuthenticatorResponse.class); if (response != null) { // send the result bundle back if set, otherwise send an error. if (mResultBundle != null) { diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 90c37d1999e1..493cb87e92d7 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -6496,7 +6496,7 @@ public class Activity extends ContextThemeWrapper Intent intent = getIntent(); if (intent != null) { try { - Uri referrer = intent.getParcelableExtra(Intent.EXTRA_REFERRER); + Uri referrer = intent.getParcelableExtra(Intent.EXTRA_REFERRER, android.net.Uri.class); if (referrer != null) { return referrer; } diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index 00ab559697f4..d9e09604bb05 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -1182,7 +1182,7 @@ public class ActivityOptions extends ComponentOptions { } catch (RuntimeException e) { Slog.w(TAG, e); } - mLaunchBounds = opts.getParcelable(KEY_LAUNCH_BOUNDS); + mLaunchBounds = opts.getParcelable(KEY_LAUNCH_BOUNDS, android.graphics.Rect.class); mAnimationType = opts.getInt(KEY_ANIM_TYPE, ANIM_UNDEFINED); switch (mAnimationType) { case ANIM_CUSTOM: @@ -1210,7 +1210,7 @@ public class ActivityOptions extends ComponentOptions { case ANIM_THUMBNAIL_ASPECT_SCALE_UP: case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN: // Unpackage the HardwareBuffer from the parceled thumbnail - final HardwareBuffer buffer = opts.getParcelable(KEY_ANIM_THUMBNAIL); + final HardwareBuffer buffer = opts.getParcelable(KEY_ANIM_THUMBNAIL, android.hardware.HardwareBuffer.class); if (buffer != null) { mThumbnail = Bitmap.wrapHardwareBuffer(buffer, null); } @@ -1223,10 +1223,10 @@ public class ActivityOptions extends ComponentOptions { break; case ANIM_SCENE_TRANSITION: - mTransitionReceiver = opts.getParcelable(KEY_TRANSITION_COMPLETE_LISTENER); + mTransitionReceiver = opts.getParcelable(KEY_TRANSITION_COMPLETE_LISTENER, android.os.ResultReceiver.class); mIsReturning = opts.getBoolean(KEY_TRANSITION_IS_RETURNING, false); mSharedElementNames = opts.getStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS); - mResultData = opts.getParcelable(KEY_RESULT_DATA); + mResultData = opts.getParcelable(KEY_RESULT_DATA, android.content.Intent.class); mResultCode = opts.getInt(KEY_RESULT_CODE); mExitCoordinatorIndex = opts.getInt(KEY_EXIT_COORDINATOR_INDEX); break; @@ -1234,10 +1234,10 @@ public class ActivityOptions extends ComponentOptions { mLockTaskMode = opts.getBoolean(KEY_LOCK_TASK_MODE, false); mLaunchDisplayId = opts.getInt(KEY_LAUNCH_DISPLAY_ID, INVALID_DISPLAY); mCallerDisplayId = opts.getInt(KEY_CALLER_DISPLAY_ID, INVALID_DISPLAY); - mLaunchTaskDisplayArea = opts.getParcelable(KEY_LAUNCH_TASK_DISPLAY_AREA_TOKEN); + mLaunchTaskDisplayArea = opts.getParcelable(KEY_LAUNCH_TASK_DISPLAY_AREA_TOKEN, android.window.WindowContainerToken.class); mLaunchTaskDisplayAreaFeatureId = opts.getInt(KEY_LAUNCH_TASK_DISPLAY_AREA_FEATURE_ID, FEATURE_UNDEFINED); - mLaunchRootTask = opts.getParcelable(KEY_LAUNCH_ROOT_TASK_TOKEN); + mLaunchRootTask = opts.getParcelable(KEY_LAUNCH_ROOT_TASK_TOKEN, android.window.WindowContainerToken.class); mLaunchTaskFragmentToken = opts.getBinder(KEY_LAUNCH_TASK_FRAGMENT_TOKEN); mLaunchWindowingMode = opts.getInt(KEY_LAUNCH_WINDOWING_MODE, WINDOWING_MODE_UNDEFINED); mLaunchActivityType = opts.getInt(KEY_LAUNCH_ACTIVITY_TYPE, ACTIVITY_TYPE_UNDEFINED); @@ -1263,23 +1263,23 @@ public class ActivityOptions extends ComponentOptions { mAnimationFinishedListener = IRemoteCallback.Stub.asInterface( opts.getBinder(KEY_ANIMATION_FINISHED_LISTENER)); } - mSourceInfo = opts.getParcelable(KEY_SOURCE_INFO); + mSourceInfo = opts.getParcelable(KEY_SOURCE_INFO, android.app.ActivityOptions.SourceInfo.class); mRotationAnimationHint = opts.getInt(KEY_ROTATION_ANIMATION_HINT, -1); mAppVerificationBundle = opts.getBundle(KEY_INSTANT_APP_VERIFICATION_BUNDLE); if (opts.containsKey(KEY_SPECS_FUTURE)) { mSpecsFuture = IAppTransitionAnimationSpecsFuture.Stub.asInterface(opts.getBinder( KEY_SPECS_FUTURE)); } - mRemoteAnimationAdapter = opts.getParcelable(KEY_REMOTE_ANIMATION_ADAPTER); + mRemoteAnimationAdapter = opts.getParcelable(KEY_REMOTE_ANIMATION_ADAPTER, android.view.RemoteAnimationAdapter.class); mLaunchCookie = opts.getBinder(KEY_LAUNCH_COOKIE); - mRemoteTransition = opts.getParcelable(KEY_REMOTE_TRANSITION); + mRemoteTransition = opts.getParcelable(KEY_REMOTE_TRANSITION, android.window.RemoteTransition.class); mOverrideTaskTransition = opts.getBoolean(KEY_OVERRIDE_TASK_TRANSITION); mSplashScreenThemeResName = opts.getString(KEY_SPLASH_SCREEN_THEME); mRemoveWithTaskOrganizer = opts.getBoolean(KEY_REMOVE_WITH_TASK_ORGANIZER); mLaunchedFromBubble = opts.getBoolean(KEY_LAUNCHED_FROM_BUBBLE); mTransientLaunch = opts.getBoolean(KEY_TRANSIENT_LAUNCH); mSplashScreenStyle = opts.getInt(KEY_SPLASH_SCREEN_STYLE); - mLaunchIntoPipParams = opts.getParcelable(KEY_LAUNCH_INTO_PIP_PARAMS); + mLaunchIntoPipParams = opts.getParcelable(KEY_LAUNCH_INTO_PIP_PARAMS, android.app.PictureInPictureParams.class); mIsEligibleForLegacyPermissionPrompt = opts.getBoolean(KEY_LEGACY_PERMISSION_PROMPT_ELIGIBLE); mDismissKeyguard = opts.getBoolean(KEY_DISMISS_KEYGUARD); diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 8a9ec0984ec7..2a83cbddd3dc 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -5885,20 +5885,20 @@ public final class ActivityThread extends ClientTransactionHandler final boolean movedToDifferentDisplay = isDifferentDisplay(activity.getDisplayId(), displayId); - final Configuration currentConfig = activity.mCurrentConfig; - final int diff = currentConfig.diffPublicOnly(newConfig); - final boolean hasPublicConfigChange = diff != 0; + final Configuration currentResConfig = activity.getResources().getConfiguration(); + final int diff = currentResConfig.diffPublicOnly(newConfig); + final boolean hasPublicResConfigChange = diff != 0; final ActivityClientRecord r = getActivityClient(activityToken); // TODO(b/173090263): Use diff instead after the improvement of AssetManager and // ResourcesImpl constructions. - final boolean shouldUpdateResources = hasPublicConfigChange - || shouldUpdateResources(activityToken, currentConfig, newConfig, amOverrideConfig, - movedToDifferentDisplay, hasPublicConfigChange); - final boolean shouldReportChange = shouldReportChange(diff, currentConfig, newConfig, + final boolean shouldUpdateResources = hasPublicResConfigChange + || shouldUpdateResources(activityToken, currentResConfig, newConfig, + amOverrideConfig, movedToDifferentDisplay, hasPublicResConfigChange); + final boolean shouldReportChange = shouldReportChange(activity.mCurrentConfig, newConfig, r != null ? r.mSizeConfigurations : null, activity.mActivityInfo.getRealConfigChanged()); // Nothing significant, don't proceed with updating and reporting. - if (!shouldUpdateResources) { + if (!shouldUpdateResources && !shouldReportChange) { return null; } @@ -5918,9 +5918,6 @@ public final class ActivityThread extends ClientTransactionHandler amOverrideConfig, contextThemeWrapperOverrideConfig); mResourcesManager.updateResourcesForActivity(activityToken, finalOverrideConfig, displayId); - activity.mConfigChangeFlags = 0; - activity.mCurrentConfig = new Configuration(newConfig); - // Apply the ContextThemeWrapper override if necessary. // NOTE: Make sure the configurations are not modified, as they are treated as immutable // in many places. @@ -5931,8 +5928,10 @@ public final class ActivityThread extends ClientTransactionHandler activity.dispatchMovedToDisplay(displayId, configToReport); } + activity.mConfigChangeFlags = 0; if (shouldReportChange) { activity.mCalled = false; + activity.mCurrentConfig = new Configuration(newConfig); activity.onConfigurationChanged(configToReport); if (!activity.mCalled) { throw new SuperNotCalledException("Activity " + activity.getLocalClassName() + @@ -5947,8 +5946,6 @@ public final class ActivityThread extends ClientTransactionHandler * Returns {@code true} if {@link Activity#onConfigurationChanged(Configuration)} should be * dispatched. * - * @param publicDiff Usually computed by {@link Configuration#diffPublicOnly(Configuration)}. - * This parameter is to prevent we compute it again. * @param currentConfig The current configuration cached in {@link Activity#mCurrentConfig}. * It is {@code null} before the first config update from the server side. * @param newConfig The updated {@link Configuration} @@ -5957,9 +5954,10 @@ public final class ActivityThread extends ClientTransactionHandler * @return {@code true} if the config change should be reported to the Activity */ @VisibleForTesting - public static boolean shouldReportChange(int publicDiff, @Nullable Configuration currentConfig, + public static boolean shouldReportChange(@Nullable Configuration currentConfig, @NonNull Configuration newConfig, @Nullable SizeConfigurationBuckets sizeBuckets, int handledConfigChanges) { + final int publicDiff = currentConfig.diffPublicOnly(newConfig); // Don't report the change if there's no public diff between current and new config. if (publicDiff == 0) { return false; diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 125f5e4e1a21..6092b307d50e 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -7693,7 +7693,7 @@ public class AppOpsManager { request.mOpNames, request.mHistoryFlags, request.mFilter, request.mBeginTimeMillis, request.mEndTimeMillis, request.mFlags, new RemoteCallback((result) -> { - final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS); + final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS, android.app.AppOpsManager.HistoricalOps.class); final long identity = Binder.clearCallingIdentity(); try { executor.execute(() -> callback.accept(ops)); @@ -7733,7 +7733,7 @@ public class AppOpsManager { request.mAttributionTag, request.mOpNames, request.mHistoryFlags, request.mFilter, request.mBeginTimeMillis, request.mEndTimeMillis, request.mFlags, new RemoteCallback((result) -> { - final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS); + final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS, android.app.AppOpsManager.HistoricalOps.class); final long identity = Binder.clearCallingIdentity(); try { executor.execute(() -> callback.accept(ops)); diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java index cd84e5671753..930750e138f8 100644 --- a/core/java/android/app/ExitTransitionCoordinator.java +++ b/core/java/android/app/ExitTransitionCoordinator.java @@ -81,7 +81,7 @@ public class ExitTransitionCoordinator extends ActivityTransitionCoordinator { switch (resultCode) { case MSG_SET_REMOTE_RECEIVER: stopCancel(); - mResultReceiver = resultData.getParcelable(KEY_REMOTE_RECEIVER); + mResultReceiver = resultData.getParcelable(KEY_REMOTE_RECEIVER, android.os.ResultReceiver.class); if (mIsCanceled) { mResultReceiver.send(MSG_CANCEL, null); mResultReceiver = null; diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index e82073380394..343adb82c8eb 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -2842,7 +2842,7 @@ public class Notification implements Parcelable visitor.accept(Uri.parse(extras.getString(EXTRA_BACKGROUND_IMAGE_URI))); } - ArrayList<Person> people = extras.getParcelableArrayList(EXTRA_PEOPLE_LIST); + ArrayList<Person> people = extras.getParcelableArrayList(EXTRA_PEOPLE_LIST, android.app.Person.class); if (people != null && !people.isEmpty()) { for (Person p : people) { visitor.accept(p.getIconUri()); @@ -3882,7 +3882,7 @@ public class Notification implements Parcelable } if (mN.extras.containsKey(EXTRA_PEOPLE_LIST)) { - ArrayList<Person> people = mN.extras.getParcelableArrayList(EXTRA_PEOPLE_LIST); + ArrayList<Person> people = mN.extras.getParcelableArrayList(EXTRA_PEOPLE_LIST, android.app.Person.class); mPersonList.addAll(people); } @@ -9777,7 +9777,7 @@ public class Notification implements Parcelable mCallType = extras.getInt(EXTRA_CALL_TYPE); mIsVideo = extras.getBoolean(EXTRA_CALL_IS_VIDEO); mPerson = extras.getParcelable(EXTRA_CALL_PERSON, Person.class); - mVerificationIcon = extras.getParcelable(EXTRA_VERIFICATION_ICON); + mVerificationIcon = extras.getParcelable(EXTRA_VERIFICATION_ICON, android.graphics.drawable.Icon.class); mVerificationText = extras.getCharSequence(EXTRA_VERIFICATION_TEXT); mAnswerIntent = extras.getParcelable(EXTRA_ANSWER_INTENT, PendingIntent.class); mDeclineIntent = extras.getParcelable(EXTRA_DECLINE_INTENT, PendingIntent.class); @@ -10895,7 +10895,7 @@ public class Notification implements Parcelable public WearableExtender(Notification notif) { Bundle wearableBundle = notif.extras.getBundle(EXTRA_WEARABLE_EXTENSIONS); if (wearableBundle != null) { - List<Action> actions = wearableBundle.getParcelableArrayList(KEY_ACTIONS); + List<Action> actions = wearableBundle.getParcelableArrayList(KEY_ACTIONS, android.app.Notification.Action.class); if (actions != null) { mActions.addAll(actions); } diff --git a/core/java/android/app/RecoverableSecurityException.java b/core/java/android/app/RecoverableSecurityException.java index 21fb2a6927aa..176f14133641 100644 --- a/core/java/android/app/RecoverableSecurityException.java +++ b/core/java/android/app/RecoverableSecurityException.java @@ -164,7 +164,7 @@ public final class RecoverableSecurityException extends SecurityException implem public static class LocalDialog extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { - final RecoverableSecurityException e = getArguments().getParcelable(TAG); + final RecoverableSecurityException e = getArguments().getParcelable(TAG, android.app.RecoverableSecurityException.class); return new AlertDialog.Builder(getActivity()) .setMessage(e.mUserMessage) .setPositiveButton(e.mUserAction.getTitle(), (dialog, which) -> { diff --git a/core/java/android/app/RemoteInput.java b/core/java/android/app/RemoteInput.java index 36c524b57fe4..88161091b6ea 100644 --- a/core/java/android/app/RemoteInput.java +++ b/core/java/android/app/RemoteInput.java @@ -429,7 +429,7 @@ public final class RemoteInput implements Parcelable { if (clipDataIntent == null) { return null; } - return clipDataIntent.getExtras().getParcelable(EXTRA_RESULTS_DATA); + return clipDataIntent.getExtras().getParcelable(EXTRA_RESULTS_DATA, android.os.Bundle.class); } /** diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java index 9fe894b75455..57576041408b 100644 --- a/core/java/android/app/SearchDialog.java +++ b/core/java/android/app/SearchDialog.java @@ -352,7 +352,7 @@ public class SearchDialog extends Dialog { public void onRestoreInstanceState(Bundle savedInstanceState) { if (savedInstanceState == null) return; - ComponentName launchComponent = savedInstanceState.getParcelable(INSTANCE_KEY_COMPONENT); + ComponentName launchComponent = savedInstanceState.getParcelable(INSTANCE_KEY_COMPONENT, android.content.ComponentName.class); Bundle appSearchData = savedInstanceState.getBundle(INSTANCE_KEY_APPDATA); String userQuery = savedInstanceState.getString(INSTANCE_KEY_USER_QUERY); diff --git a/core/java/android/app/SharedElementCallback.java b/core/java/android/app/SharedElementCallback.java index 8eb7e7246976..594d297a1979 100644 --- a/core/java/android/app/SharedElementCallback.java +++ b/core/java/android/app/SharedElementCallback.java @@ -234,8 +234,8 @@ public abstract class SharedElementCallback { View view = null; if (snapshot instanceof Bundle) { Bundle bundle = (Bundle) snapshot; - HardwareBuffer buffer = bundle.getParcelable(BUNDLE_SNAPSHOT_HARDWARE_BUFFER); - Bitmap bitmap = bundle.getParcelable(BUNDLE_SNAPSHOT_BITMAP); + HardwareBuffer buffer = bundle.getParcelable(BUNDLE_SNAPSHOT_HARDWARE_BUFFER, android.hardware.HardwareBuffer.class); + Bitmap bitmap = bundle.getParcelable(BUNDLE_SNAPSHOT_BITMAP, android.graphics.Bitmap.class); if (buffer == null && bitmap == null) { return null; } diff --git a/core/java/android/app/admin/DelegatedAdminReceiver.java b/core/java/android/app/admin/DelegatedAdminReceiver.java index c74ddb285644..30509d649736 100644 --- a/core/java/android/app/admin/DelegatedAdminReceiver.java +++ b/core/java/android/app/admin/DelegatedAdminReceiver.java @@ -156,7 +156,7 @@ public class DelegatedAdminReceiver extends BroadcastReceiver { if (ACTION_CHOOSE_PRIVATE_KEY_ALIAS.equals(action)) { int uid = intent.getIntExtra(EXTRA_CHOOSE_PRIVATE_KEY_SENDER_UID, -1); - Uri uri = intent.getParcelableExtra(EXTRA_CHOOSE_PRIVATE_KEY_URI); + Uri uri = intent.getParcelableExtra(EXTRA_CHOOSE_PRIVATE_KEY_URI, android.net.Uri.class); String alias = intent.getStringExtra(EXTRA_CHOOSE_PRIVATE_KEY_ALIAS); String chosenAlias = onChoosePrivateKeyAlias(context, intent, uid, uri, alias); setResultData(chosenAlias); diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java index 27e8c46ca548..f21e11ab35cc 100644 --- a/core/java/android/app/admin/DeviceAdminReceiver.java +++ b/core/java/android/app/admin/DeviceAdminReceiver.java @@ -1179,11 +1179,11 @@ public class DeviceAdminReceiver extends BroadcastReceiver { } if (ACTION_PASSWORD_CHANGED.equals(action)) { - onPasswordChanged(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER)); + onPasswordChanged(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class)); } else if (ACTION_PASSWORD_FAILED.equals(action)) { - onPasswordFailed(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER)); + onPasswordFailed(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class)); } else if (ACTION_PASSWORD_SUCCEEDED.equals(action)) { - onPasswordSucceeded(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER)); + onPasswordSucceeded(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class)); } else if (ACTION_DEVICE_ADMIN_ENABLED.equals(action)) { onEnabled(context, intent); } else if (ACTION_DEVICE_ADMIN_DISABLE_REQUESTED.equals(action)) { @@ -1195,12 +1195,12 @@ public class DeviceAdminReceiver extends BroadcastReceiver { } else if (ACTION_DEVICE_ADMIN_DISABLED.equals(action)) { onDisabled(context, intent); } else if (ACTION_PASSWORD_EXPIRING.equals(action)) { - onPasswordExpiring(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER)); + onPasswordExpiring(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class)); } else if (ACTION_PROFILE_PROVISIONING_COMPLETE.equals(action)) { onProfileProvisioningComplete(context, intent); } else if (ACTION_CHOOSE_PRIVATE_KEY_ALIAS.equals(action)) { int uid = intent.getIntExtra(EXTRA_CHOOSE_PRIVATE_KEY_SENDER_UID, -1); - Uri uri = intent.getParcelableExtra(EXTRA_CHOOSE_PRIVATE_KEY_URI); + Uri uri = intent.getParcelableExtra(EXTRA_CHOOSE_PRIVATE_KEY_URI, android.net.Uri.class); String alias = intent.getStringExtra(EXTRA_CHOOSE_PRIVATE_KEY_ALIAS); String chosenAlias = onChoosePrivateKeyAlias(context, intent, uid, uri, alias); setResultData(chosenAlias); @@ -1228,22 +1228,22 @@ public class DeviceAdminReceiver extends BroadcastReceiver { int networkLogsCount = intent.getIntExtra(EXTRA_NETWORK_LOGS_COUNT, 0); onNetworkLogsAvailable(context, intent, batchToken, networkLogsCount); } else if (ACTION_USER_ADDED.equals(action)) { - onUserAdded(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER)); + onUserAdded(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class)); } else if (ACTION_USER_REMOVED.equals(action)) { - onUserRemoved(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER)); + onUserRemoved(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class)); } else if (ACTION_USER_STARTED.equals(action)) { - onUserStarted(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER)); + onUserStarted(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class)); } else if (ACTION_USER_STOPPED.equals(action)) { - onUserStopped(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER)); + onUserStopped(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class)); } else if (ACTION_USER_SWITCHED.equals(action)) { - onUserSwitched(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER)); + onUserSwitched(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class)); } else if (ACTION_TRANSFER_OWNERSHIP_COMPLETE.equals(action)) { PersistableBundle bundle = - intent.getParcelableExtra(EXTRA_TRANSFER_OWNERSHIP_ADMIN_EXTRAS_BUNDLE); + intent.getParcelableExtra(EXTRA_TRANSFER_OWNERSHIP_ADMIN_EXTRAS_BUNDLE, android.os.PersistableBundle.class); onTransferOwnershipComplete(context, bundle); } else if (ACTION_AFFILIATED_PROFILE_TRANSFER_OWNERSHIP_COMPLETE.equals(action)) { onTransferAffiliatedProfileOwnershipComplete(context, - intent.getParcelableExtra(Intent.EXTRA_USER)); + intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class)); } else if (ACTION_OPERATION_SAFETY_STATE_CHANGED.equals(action)) { onOperationSafetyStateChanged(context, intent); } else if (ACTION_COMPLIANCE_ACKNOWLEDGEMENT_REQUIRED.equals(action)) { diff --git a/core/java/android/app/ambientcontext/AmbientContextManager.java b/core/java/android/app/ambientcontext/AmbientContextManager.java index dd1dd0c75f76..308c5edfd0f4 100644 --- a/core/java/android/app/ambientcontext/AmbientContextManager.java +++ b/core/java/android/app/ambientcontext/AmbientContextManager.java @@ -117,7 +117,7 @@ public final class AmbientContextManager { */ @NonNull public static List<AmbientContextEvent> getEventsFromIntent(@NonNull Intent intent) { if (intent.hasExtra(AmbientContextManager.EXTRA_AMBIENT_CONTEXT_EVENTS)) { - return intent.getParcelableArrayListExtra(EXTRA_AMBIENT_CONTEXT_EVENTS); + return intent.getParcelableArrayListExtra(EXTRA_AMBIENT_CONTEXT_EVENTS, android.app.ambientcontext.AmbientContextEvent.class); } else { return new ArrayList<>(); } diff --git a/core/java/android/app/assist/TEST_MAPPING b/core/java/android/app/assist/TEST_MAPPING new file mode 100644 index 000000000000..33a41c972386 --- /dev/null +++ b/core/java/android/app/assist/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "imports": [ + { + "path": "frameworks/base/services/voiceinteraction" + } + ] +} diff --git a/core/java/android/app/slice/SliceManager.java b/core/java/android/app/slice/SliceManager.java index ed4ea749c181..1e4934ebb6f5 100644 --- a/core/java/android/app/slice/SliceManager.java +++ b/core/java/android/app/slice/SliceManager.java @@ -231,7 +231,7 @@ public class SliceManager { extras.putParcelable(SliceProvider.EXTRA_BIND_URI, uri); final Bundle res = provider.call( SliceProvider.METHOD_GET_DESCENDANTS, null, extras); - return res.getParcelableArrayList(SliceProvider.EXTRA_SLICE_DESCENDANTS); + return res.getParcelableArrayList(SliceProvider.EXTRA_SLICE_DESCENDANTS, android.net.Uri.class); } } catch (RemoteException e) { Log.e(TAG, "Unable to get slice descendants", e); @@ -264,7 +264,7 @@ public class SliceManager { if (res == null) { return null; } - return res.getParcelable(SliceProvider.EXTRA_SLICE); + return res.getParcelable(SliceProvider.EXTRA_SLICE, android.app.slice.Slice.class); } catch (RemoteException e) { // Arbitrary and not worth documenting, as Activity // Manager will kill this process shortly anyway. @@ -323,7 +323,7 @@ public class SliceManager { if (res == null) { return null; } - return res.getParcelable(SliceProvider.EXTRA_SLICE); + return res.getParcelable(SliceProvider.EXTRA_SLICE, android.net.Uri.class); } catch (RemoteException e) { // Arbitrary and not worth documenting, as Activity // Manager will kill this process shortly anyway. @@ -403,7 +403,7 @@ public class SliceManager { if (res == null) { return null; } - return res.getParcelable(SliceProvider.EXTRA_SLICE); + return res.getParcelable(SliceProvider.EXTRA_SLICE, android.app.slice.Slice.class); } catch (RemoteException e) { // Arbitrary and not worth documenting, as Activity // Manager will kill this process shortly anyway. diff --git a/core/java/android/app/slice/SliceProvider.java b/core/java/android/app/slice/SliceProvider.java index e6c88a31a1b2..63835cb5446b 100644 --- a/core/java/android/app/slice/SliceProvider.java +++ b/core/java/android/app/slice/SliceProvider.java @@ -352,8 +352,8 @@ public abstract class SliceProvider extends ContentProvider { public Bundle call(String method, String arg, Bundle extras) { if (method.equals(METHOD_SLICE)) { Uri uri = getUriWithoutUserId(validateIncomingUriOrNull( - extras.getParcelable(EXTRA_BIND_URI))); - List<SliceSpec> supportedSpecs = extras.getParcelableArrayList(EXTRA_SUPPORTED_SPECS); + extras.getParcelable(EXTRA_BIND_URI, android.net.Uri.class))); + List<SliceSpec> supportedSpecs = extras.getParcelableArrayList(EXTRA_SUPPORTED_SPECS, android.app.slice.SliceSpec.class); String callingPackage = getCallingPackage(); int callingUid = Binder.getCallingUid(); @@ -364,10 +364,10 @@ public abstract class SliceProvider extends ContentProvider { b.putParcelable(EXTRA_SLICE, s); return b; } else if (method.equals(METHOD_MAP_INTENT)) { - Intent intent = extras.getParcelable(EXTRA_INTENT); + Intent intent = extras.getParcelable(EXTRA_INTENT, android.content.Intent.class); if (intent == null) return null; Uri uri = validateIncomingUriOrNull(onMapIntentToUri(intent)); - List<SliceSpec> supportedSpecs = extras.getParcelableArrayList(EXTRA_SUPPORTED_SPECS); + List<SliceSpec> supportedSpecs = extras.getParcelableArrayList(EXTRA_SUPPORTED_SPECS, android.app.slice.SliceSpec.class); Bundle b = new Bundle(); if (uri != null) { Slice s = handleBindSlice(uri, supportedSpecs, getCallingPackage(), @@ -378,7 +378,7 @@ public abstract class SliceProvider extends ContentProvider { } return b; } else if (method.equals(METHOD_MAP_ONLY_INTENT)) { - Intent intent = extras.getParcelable(EXTRA_INTENT); + Intent intent = extras.getParcelable(EXTRA_INTENT, android.content.Intent.class); if (intent == null) return null; Uri uri = validateIncomingUriOrNull(onMapIntentToUri(intent)); Bundle b = new Bundle(); @@ -386,21 +386,21 @@ public abstract class SliceProvider extends ContentProvider { return b; } else if (method.equals(METHOD_PIN)) { Uri uri = getUriWithoutUserId(validateIncomingUriOrNull( - extras.getParcelable(EXTRA_BIND_URI))); + extras.getParcelable(EXTRA_BIND_URI, android.net.Uri.class))); if (Binder.getCallingUid() != Process.SYSTEM_UID) { throw new SecurityException("Only the system can pin/unpin slices"); } handlePinSlice(uri); } else if (method.equals(METHOD_UNPIN)) { Uri uri = getUriWithoutUserId(validateIncomingUriOrNull( - extras.getParcelable(EXTRA_BIND_URI))); + extras.getParcelable(EXTRA_BIND_URI, android.net.Uri.class))); if (Binder.getCallingUid() != Process.SYSTEM_UID) { throw new SecurityException("Only the system can pin/unpin slices"); } handleUnpinSlice(uri); } else if (method.equals(METHOD_GET_DESCENDANTS)) { Uri uri = getUriWithoutUserId( - validateIncomingUriOrNull(extras.getParcelable(EXTRA_BIND_URI))); + validateIncomingUriOrNull(extras.getParcelable(EXTRA_BIND_URI, android.net.Uri.class))); Bundle b = new Bundle(); b.putParcelableArrayList(EXTRA_SLICE_DESCENDANTS, new ArrayList<>(handleGetDescendants(uri))); diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java index 7b9d37e7136d..37794531dfa3 100644 --- a/core/java/android/content/ContentResolver.java +++ b/core/java/android/content/ContentResolver.java @@ -980,7 +980,7 @@ public abstract class ContentResolver implements ContentInterface { @Override public void onResult(Bundle result) { synchronized (this) { - ParcelableException e = result.getParcelable(REMOTE_CALLBACK_ERROR); + ParcelableException e = result.getParcelable(REMOTE_CALLBACK_ERROR, android.os.ParcelableException.class); if (e != null) { Throwable t = e.getCause(); if (t instanceof RuntimeException) { @@ -1021,7 +1021,7 @@ public abstract class ContentResolver implements ContentInterface { private static class UriResultListener extends ResultListener<Uri> { @Override protected Uri getResultFromBundle(Bundle result) { - return result.getParcelable(REMOTE_CALLBACK_RESULT); + return result.getParcelable(REMOTE_CALLBACK_RESULT, android.net.Uri.class); } } diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 7a88a057fb77..26b2f071e3f5 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -11940,7 +11940,7 @@ public class Intent implements Parcelable, Cloneable { // passed via Bluetooth intents if (mAction != null && mAction.startsWith("android.bluetooth.") && hasExtra(BluetoothDevice.EXTRA_DEVICE)) { - final BluetoothDevice device = getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + final BluetoothDevice device = getParcelableExtra(BluetoothDevice.EXTRA_DEVICE, BluetoothDevice.class); if (device != null) { device.prepareToEnterProcess(source); } @@ -11989,12 +11989,12 @@ public class Intent implements Parcelable, Cloneable { } String action = getAction(); if (ACTION_SEND.equals(action)) { - final Uri stream = getParcelableExtra(EXTRA_STREAM); + final Uri stream = getParcelableExtra(EXTRA_STREAM, Uri.class); if (stream != null) { putExtra(EXTRA_STREAM, maybeAddUserId(stream, contentUserHint)); } } else if (ACTION_SEND_MULTIPLE.equals(action)) { - final ArrayList<Uri> streams = getParcelableArrayListExtra(EXTRA_STREAM); + final ArrayList<Uri> streams = getParcelableArrayListExtra(EXTRA_STREAM, Uri.class); if (streams != null) { ArrayList<Uri> newStreams = new ArrayList<Uri>(); for (int i = 0; i < streams.size(); i++) { @@ -12003,7 +12003,7 @@ public class Intent implements Parcelable, Cloneable { putParcelableArrayListExtra(EXTRA_STREAM, newStreams); } } else if (isImageCaptureIntent()) { - final Uri output = getParcelableExtra(MediaStore.EXTRA_OUTPUT); + final Uri output = getParcelableExtra(MediaStore.EXTRA_OUTPUT, Uri.class); if (output != null) { putExtra(MediaStore.EXTRA_OUTPUT, maybeAddUserId(output, contentUserHint)); } @@ -12047,7 +12047,7 @@ public class Intent implements Parcelable, Cloneable { boolean migrated = false; try { - final Intent intent = getParcelableExtra(EXTRA_INTENT); + final Intent intent = getParcelableExtra(EXTRA_INTENT, Intent.class); if (intent != null) { migrated |= intent.migrateExtraStreamToClipData(context); } @@ -12069,7 +12069,7 @@ public class Intent implements Parcelable, Cloneable { } else if (ACTION_SEND.equals(action)) { try { - final Uri stream = getParcelableExtra(EXTRA_STREAM); + final Uri stream = getParcelableExtra(EXTRA_STREAM, Uri.class); final CharSequence text = getCharSequenceExtra(EXTRA_TEXT); final String htmlText = getStringExtra(EXTRA_HTML_TEXT); if (stream != null || text != null || htmlText != null) { @@ -12085,7 +12085,7 @@ public class Intent implements Parcelable, Cloneable { } else if (ACTION_SEND_MULTIPLE.equals(action)) { try { - final ArrayList<Uri> streams = getParcelableArrayListExtra(EXTRA_STREAM); + final ArrayList<Uri> streams = getParcelableArrayListExtra(EXTRA_STREAM, Uri.class); final ArrayList<CharSequence> texts = getCharSequenceArrayListExtra(EXTRA_TEXT); final ArrayList<String> htmlTexts = getStringArrayListExtra(EXTRA_HTML_TEXT); int num = -1; @@ -12124,7 +12124,7 @@ public class Intent implements Parcelable, Cloneable { } else if (isImageCaptureIntent()) { Uri output; try { - output = getParcelableExtra(MediaStore.EXTRA_OUTPUT); + output = getParcelableExtra(MediaStore.EXTRA_OUTPUT, Uri.class); } catch (ClassCastException e) { return false; } diff --git a/core/java/android/content/SyncActivityTooManyDeletes.java b/core/java/android/content/SyncActivityTooManyDeletes.java index 093fb0821a96..1a4eedd572b0 100644 --- a/core/java/android/content/SyncActivityTooManyDeletes.java +++ b/core/java/android/content/SyncActivityTooManyDeletes.java @@ -54,7 +54,7 @@ public class SyncActivityTooManyDeletes extends Activity } mNumDeletes = extras.getLong("numDeletes"); - mAccount = (Account) extras.getParcelable("account"); + mAccount = (Account) extras.getParcelable("account", android.accounts.Account.class); mAuthority = extras.getString("authority"); mProvider = extras.getString("provider"); diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java index 301d1bbc8e9d..f780f815fa89 100644 --- a/core/java/android/content/pm/LauncherApps.java +++ b/core/java/android/content/pm/LauncherApps.java @@ -2062,7 +2062,7 @@ public class LauncherApps { * the {@link #EXTRA_PIN_ITEM_REQUEST} extra. */ public PinItemRequest getPinItemRequest(Intent intent) { - return intent.getParcelableExtra(EXTRA_PIN_ITEM_REQUEST); + return intent.getParcelableExtra(EXTRA_PIN_ITEM_REQUEST, android.content.pm.LauncherApps.PinItemRequest.class); } /** diff --git a/core/java/android/hardware/location/ContextHubIntentEvent.java b/core/java/android/hardware/location/ContextHubIntentEvent.java index 3e8f4219a485..06c533401e27 100644 --- a/core/java/android/hardware/location/ContextHubIntentEvent.java +++ b/core/java/android/hardware/location/ContextHubIntentEvent.java @@ -98,7 +98,7 @@ public class ContextHubIntentEvent { Objects.requireNonNull(intent, "Intent cannot be null"); hasExtraOrThrow(intent, ContextHubManager.EXTRA_CONTEXT_HUB_INFO); - ContextHubInfo info = intent.getParcelableExtra(ContextHubManager.EXTRA_CONTEXT_HUB_INFO); + ContextHubInfo info = intent.getParcelableExtra(ContextHubManager.EXTRA_CONTEXT_HUB_INFO, android.hardware.location.ContextHubInfo.class); if (info == null) { throw new IllegalArgumentException("ContextHubInfo extra was null"); } @@ -117,7 +117,7 @@ public class ContextHubIntentEvent { if (eventType == ContextHubManager.EVENT_NANOAPP_MESSAGE) { hasExtraOrThrow(intent, ContextHubManager.EXTRA_MESSAGE); NanoAppMessage message = - intent.getParcelableExtra(ContextHubManager.EXTRA_MESSAGE); + intent.getParcelableExtra(ContextHubManager.EXTRA_MESSAGE, android.hardware.location.NanoAppMessage.class); if (message == null) { throw new IllegalArgumentException("NanoAppMessage extra was null"); } diff --git a/core/java/android/hardware/radio/RadioMetadata.java b/core/java/android/hardware/radio/RadioMetadata.java index a882c2fe877c..b7bf783754f7 100644 --- a/core/java/android/hardware/radio/RadioMetadata.java +++ b/core/java/android/hardware/radio/RadioMetadata.java @@ -384,7 +384,7 @@ public final class RadioMetadata implements Parcelable { public Bitmap getBitmap(String key) { Bitmap bmp = null; try { - bmp = mBundle.getParcelable(key); + bmp = mBundle.getParcelable(key, android.graphics.Bitmap.class); } catch (Exception e) { // ignore, value was not a bitmap Log.w(TAG, "Failed to retrieve a key as Bitmap.", e); @@ -419,7 +419,7 @@ public final class RadioMetadata implements Parcelable { public Clock getClock(String key) { Clock clock = null; try { - clock = mBundle.getParcelable(key); + clock = mBundle.getParcelable(key, android.hardware.radio.RadioMetadata.Clock.class); } catch (Exception e) { // ignore, value was not a clock. Log.w(TAG, "Failed to retrieve a key as Clock.", e); diff --git a/core/java/android/net/ScoredNetwork.java b/core/java/android/net/ScoredNetwork.java index a46bdd9ac37e..758367d30eb4 100644 --- a/core/java/android/net/ScoredNetwork.java +++ b/core/java/android/net/ScoredNetwork.java @@ -299,7 +299,7 @@ public class ScoredNetwork implements Parcelable { public int calculateBadge(int rssi) { if (attributes != null && attributes.containsKey(ATTRIBUTES_KEY_BADGING_CURVE)) { RssiCurve badgingCurve = - attributes.getParcelable(ATTRIBUTES_KEY_BADGING_CURVE); + attributes.getParcelable(ATTRIBUTES_KEY_BADGING_CURVE, android.net.RssiCurve.class); return badgingCurve.lookupScore(rssi); } diff --git a/core/java/android/nfc/tech/Ndef.java b/core/java/android/nfc/tech/Ndef.java index 225636565480..39c355ad918a 100644 --- a/core/java/android/nfc/tech/Ndef.java +++ b/core/java/android/nfc/tech/Ndef.java @@ -161,7 +161,7 @@ public final class Ndef extends BasicTagTechnology { if (extras != null) { mMaxNdefSize = extras.getInt(EXTRA_NDEF_MAXLENGTH); mCardState = extras.getInt(EXTRA_NDEF_CARDSTATE); - mNdefMsg = extras.getParcelable(EXTRA_NDEF_MSG); + mNdefMsg = extras.getParcelable(EXTRA_NDEF_MSG, android.nfc.NdefMessage.class); mNdefType = extras.getInt(EXTRA_NDEF_TYPE); } else { throw new NullPointerException("NDEF tech extras are null."); diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index 1dedc2666582..aa6155869f64 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -33,6 +33,7 @@ import android.util.ArraySet; import android.util.ExceptionUtils; import android.util.Log; import android.util.MathUtils; +import android.util.Pair; import android.util.Size; import android.util.SizeF; import android.util.Slog; @@ -3034,7 +3035,7 @@ public final class Parcel { switch (code) { case EX_PARCELABLE: if (readInt() > 0) { - return (Exception) readParcelable(Parcelable.class.getClassLoader()); + return (Exception) readParcelable(Parcelable.class.getClassLoader(), java.lang.Exception.class); } else { return new RuntimeException(msg + " [missing Parcelable]"); } @@ -4865,28 +4866,36 @@ public final class Parcel { if (name == null) { return null; } - Parcelable.Creator<?> creator; - HashMap<String, Parcelable.Creator<?>> map; - synchronized (mCreators) { - map = mCreators.get(loader); + + Pair<Parcelable.Creator<?>, Class<?>> creatorAndParcelableClass; + synchronized (sPairedCreators) { + HashMap<String, Pair<Parcelable.Creator<?>, Class<?>>> map = + sPairedCreators.get(loader); if (map == null) { - map = new HashMap<>(); - mCreators.put(loader, map); + sPairedCreators.put(loader, new HashMap<>()); + mCreators.put(loader, new HashMap<>()); + creatorAndParcelableClass = null; + } else { + creatorAndParcelableClass = map.get(name); } - creator = map.get(name); } - if (creator != null) { + + if (creatorAndParcelableClass != null) { + Parcelable.Creator<?> creator = creatorAndParcelableClass.first; + Class<?> parcelableClass = creatorAndParcelableClass.second; if (clazz != null) { - Class<?> parcelableClass = creator.getClass().getEnclosingClass(); if (!clazz.isAssignableFrom(parcelableClass)) { throw new BadTypeParcelableException("Parcelable creator " + name + " is not " + "a subclass of required class " + clazz.getName() + " provided in the parameter"); } } + return (Parcelable.Creator<T>) creator; } + Parcelable.Creator<?> creator; + Class<?> parcelableClass; try { // If loader == null, explicitly emulate Class.forName(String) "caller // classloader" behavior. @@ -4894,7 +4903,7 @@ public final class Parcel { (loader == null ? getClass().getClassLoader() : loader); // Avoid initializing the Parcelable class until we know it implements // Parcelable and has the necessary CREATOR field. http://b/1171613. - Class<?> parcelableClass = Class.forName(name, false /* initialize */, + parcelableClass = Class.forName(name, false /* initialize */, parcelableClassLoader); if (!Parcelable.class.isAssignableFrom(parcelableClass)) { throw new BadParcelableException("Parcelable protocol requires subclassing " @@ -4941,8 +4950,9 @@ public final class Parcel { + "CREATOR on class " + name); } - synchronized (mCreators) { - map.put(name, creator); + synchronized (sPairedCreators) { + sPairedCreators.get(loader).put(name, Pair.create(creator, parcelableClass)); + mCreators.get(loader).put(name, creator); } return (Parcelable.Creator<T>) creator; @@ -5093,12 +5103,17 @@ public final class Parcel { } } - // Cache of previously looked up CREATOR.createFromParcel() methods for - // particular classes. Keys are the names of the classes, values are - // Method objects. + + // Left due to the UnsupportedAppUsage. Do not use anymore - use sPairedCreators instead @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) - private static final HashMap<ClassLoader,HashMap<String,Parcelable.Creator<?>>> - mCreators = new HashMap<>(); + private static final HashMap<ClassLoader, HashMap<String, Parcelable.Creator<?>>> + mCreators = new HashMap<>(); + + // Cache of previously looked up CREATOR.createFromParcel() methods for particular classes. + // Keys are the names of the classes, values are a pair consisting of a parcelable creator, + // and the class of the parcelable type for the object. + private static final HashMap<ClassLoader, HashMap<String, + Pair<Parcelable.Creator<?>, Class<?>>>> sPairedCreators = new HashMap<>(); /** @hide for internal use only. */ static protected final Parcel obtain(int obj) { diff --git a/core/java/android/os/image/DynamicSystemClient.java b/core/java/android/os/image/DynamicSystemClient.java index 5aa4e27fc2f3..63259edeae7d 100644 --- a/core/java/android/os/image/DynamicSystemClient.java +++ b/core/java/android/os/image/DynamicSystemClient.java @@ -420,7 +420,7 @@ public class DynamicSystemClient { Bundle bundle = (Bundle) msg.obj; long progress = bundle.getLong(KEY_INSTALLED_SIZE); ParcelableException t = (ParcelableException) bundle.getSerializable( - KEY_EXCEPTION_DETAIL); + KEY_EXCEPTION_DETAIL, android.os.ParcelableException.class); Throwable detail = t == null ? null : t.getCause(); diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java index 53b1dab9f760..f6bdc18c29ec 100644 --- a/core/java/android/preference/PreferenceActivity.java +++ b/core/java/android/preference/PreferenceActivity.java @@ -578,7 +578,7 @@ public abstract class PreferenceActivity extends ListActivity implements if (savedInstanceState != null) { // We are restarting from a previous saved state; used that to // initialize, instead of starting fresh. - ArrayList<Header> headers = savedInstanceState.getParcelableArrayList(HEADERS_TAG); + ArrayList<Header> headers = savedInstanceState.getParcelableArrayList(HEADERS_TAG, android.preference.PreferenceActivity.Header.class); if (headers != null) { mHeaders.addAll(headers); int curHeader = savedInstanceState.getInt(CUR_HEADER_TAG, diff --git a/core/java/android/preference/RingtonePreference.java b/core/java/android/preference/RingtonePreference.java index c6d8c08c9141..e15244ac0df0 100644 --- a/core/java/android/preference/RingtonePreference.java +++ b/core/java/android/preference/RingtonePreference.java @@ -248,7 +248,7 @@ public class RingtonePreference extends Preference implements if (requestCode == mRequestCode) { if (data != null) { - Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI); + Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI, android.net.Uri.class); if (callChangeListener(uri != null ? uri.toString() : "")) { onSaveRingtone(uri); diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java index a5e2f33d4418..931adb55a686 100644 --- a/core/java/android/print/PrintManager.java +++ b/core/java/android/print/PrintManager.java @@ -529,8 +529,8 @@ public final class PrintManager { Bundle result = mService.print(printJobName, delegate, attributes, mContext.getPackageName(), mAppId, mUserId); if (result != null) { - PrintJobInfo printJob = result.getParcelable(EXTRA_PRINT_JOB); - IntentSender intent = result.getParcelable(EXTRA_PRINT_DIALOG_INTENT); + PrintJobInfo printJob = result.getParcelable(EXTRA_PRINT_JOB, android.print.PrintJobInfo.class); + IntentSender intent = result.getParcelable(EXTRA_PRINT_DIALOG_INTENT, android.content.IntentSender.class); if (printJob == null || intent == null) { return null; } diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java index 3c1b4ba8f8b5..d50ba8de8fa6 100644 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -8448,7 +8448,7 @@ public final class ContactsContract { Bundle response = contentResolver.call(ContactsContract.AUTHORITY_URI, ContactsContract.SimContacts.QUERY_SIM_ACCOUNTS_METHOD, null, null); - List<SimAccount> result = response.getParcelableArrayList(KEY_SIM_ACCOUNTS); + List<SimAccount> result = response.getParcelableArrayList(KEY_SIM_ACCOUNTS, android.provider.ContactsContract.SimAccount.class); if (result == null) { result = new ArrayList<>(); @@ -8821,7 +8821,7 @@ public final class ContactsContract { public static Account getDefaultAccount(@NonNull ContentResolver resolver) { Bundle response = resolver.call(ContactsContract.AUTHORITY_URI, QUERY_DEFAULT_ACCOUNT_METHOD, null, null); - return response.getParcelable(KEY_DEFAULT_ACCOUNT); + return response.getParcelable(KEY_DEFAULT_ACCOUNT, android.accounts.Account.class); } /** diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java index 620fa6517ca5..1884d569adc3 100644 --- a/core/java/android/provider/DocumentsContract.java +++ b/core/java/android/provider/DocumentsContract.java @@ -1379,7 +1379,7 @@ public final class DocumentsContract { final Bundle out = content.call(parentDocumentUri.getAuthority(), METHOD_CREATE_DOCUMENT, null, in); - return out.getParcelable(DocumentsContract.EXTRA_URI); + return out.getParcelable(DocumentsContract.EXTRA_URI, android.net.Uri.class); } catch (Exception e) { Log.w(TAG, "Failed to create document", e); rethrowIfNecessary(e); @@ -1445,7 +1445,7 @@ public final class DocumentsContract { final Bundle out = content.call(documentUri.getAuthority(), METHOD_RENAME_DOCUMENT, null, in); - final Uri outUri = out.getParcelable(DocumentsContract.EXTRA_URI); + final Uri outUri = out.getParcelable(DocumentsContract.EXTRA_URI, android.net.Uri.class); return (outUri != null) ? outUri : documentUri; } catch (Exception e) { Log.w(TAG, "Failed to rename document", e); @@ -1494,7 +1494,7 @@ public final class DocumentsContract { final Bundle out = content.call(sourceDocumentUri.getAuthority(), METHOD_COPY_DOCUMENT, null, in); - return out.getParcelable(DocumentsContract.EXTRA_URI); + return out.getParcelable(DocumentsContract.EXTRA_URI, android.net.Uri.class); } catch (Exception e) { Log.w(TAG, "Failed to copy document", e); rethrowIfNecessary(e); @@ -1522,7 +1522,7 @@ public final class DocumentsContract { final Bundle out = content.call(sourceDocumentUri.getAuthority(), METHOD_MOVE_DOCUMENT, null, in); - return out.getParcelable(DocumentsContract.EXTRA_URI); + return out.getParcelable(DocumentsContract.EXTRA_URI, android.net.Uri.class); } catch (Exception e) { Log.w(TAG, "Failed to move document", e); rethrowIfNecessary(e); @@ -1642,7 +1642,7 @@ public final class DocumentsContract { final Bundle out = content.call(treeUri.getAuthority(), METHOD_FIND_DOCUMENT_PATH, null, in); - return out.getParcelable(DocumentsContract.EXTRA_RESULT); + return out.getParcelable(DocumentsContract.EXTRA_RESULT, android.provider.DocumentsContract.Path.class); } catch (Exception e) { Log.w(TAG, "Failed to find path", e); rethrowIfNecessary(e); @@ -1715,7 +1715,7 @@ public final class DocumentsContract { final Bundle out = content.call(uri.getAuthority(), METHOD_CREATE_WEB_LINK_INTENT, null, in); - return out.getParcelable(DocumentsContract.EXTRA_RESULT); + return out.getParcelable(DocumentsContract.EXTRA_RESULT, android.content.IntentSender.class); } catch (Exception e) { Log.w(TAG, "Failed to create a web link intent", e); rethrowIfNecessary(e); diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java index a5a24c0f1013..07d500176fe5 100644 --- a/core/java/android/provider/DocumentsProvider.java +++ b/core/java/android/provider/DocumentsProvider.java @@ -219,9 +219,9 @@ public abstract class DocumentsProvider extends ContentProvider { /** {@hide} */ private void enforceTreeForExtraUris(Bundle extras) { - enforceTree(extras.getParcelable(DocumentsContract.EXTRA_URI)); - enforceTree(extras.getParcelable(DocumentsContract.EXTRA_PARENT_URI)); - enforceTree(extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI)); + enforceTree(extras.getParcelable(DocumentsContract.EXTRA_URI, android.net.Uri.class)); + enforceTree(extras.getParcelable(DocumentsContract.EXTRA_PARENT_URI, android.net.Uri.class)); + enforceTree(extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI, android.net.Uri.class)); } /** {@hide} */ @@ -1091,11 +1091,11 @@ public abstract class DocumentsProvider extends ContentProvider { enforceTreeForExtraUris(extras); final Uri extraUri = validateIncomingNullableUri( - extras.getParcelable(DocumentsContract.EXTRA_URI)); + extras.getParcelable(DocumentsContract.EXTRA_URI, android.net.Uri.class)); final Uri extraTargetUri = validateIncomingNullableUri( - extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI)); + extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI, android.net.Uri.class)); final Uri extraParentUri = validateIncomingNullableUri( - extras.getParcelable(DocumentsContract.EXTRA_PARENT_URI)); + extras.getParcelable(DocumentsContract.EXTRA_PARENT_URI, android.net.Uri.class)); if (METHOD_EJECT_ROOT.equals(method)) { // Given that certain system apps can hold MOUNT_UNMOUNT permission, but only apps @@ -1436,7 +1436,7 @@ public abstract class DocumentsProvider extends ContentProvider { enforceTree(uri); final String documentId = getDocumentId(uri); if (opts != null && opts.containsKey(ContentResolver.EXTRA_SIZE)) { - final Point sizeHint = opts.getParcelable(ContentResolver.EXTRA_SIZE); + final Point sizeHint = opts.getParcelable(ContentResolver.EXTRA_SIZE, android.graphics.Point.class); return openDocumentThumbnail(documentId, sizeHint, signal); } if ("*/*".equals(mimeTypeFilter)) { diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index a513d5eb961b..6c5066f4e5db 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -3168,7 +3168,7 @@ public final class Settings { synchronized (NameValueCache.this) { if (needsGenerationTracker) { MemoryIntArray array = b.getParcelable( - CALL_METHOD_TRACK_GENERATION_KEY); + CALL_METHOD_TRACK_GENERATION_KEY, android.util.MemoryIntArray.class); final int index = b.getInt( CALL_METHOD_GENERATION_INDEX_KEY, -1); if (array != null && index >= 0) { @@ -3354,7 +3354,7 @@ public final class Settings { // All flags for the namespace Map<String, String> flagsToValues = - (HashMap) b.getSerializable(Settings.NameValueTable.VALUE); + (HashMap) b.getSerializable(Settings.NameValueTable.VALUE, java.util.HashMap.class); // Only the flags requested by the caller if (!names.isEmpty()) { for (Map.Entry<String, String> flag : flagsToValues.entrySet()) { @@ -3369,7 +3369,7 @@ public final class Settings { synchronized (NameValueCache.this) { if (needsGenerationTracker) { MemoryIntArray array = b.getParcelable( - CALL_METHOD_TRACK_GENERATION_KEY); + CALL_METHOD_TRACK_GENERATION_KEY, android.util.MemoryIntArray.class); final int index = b.getInt( CALL_METHOD_GENERATION_INDEX_KEY, -1); if (array != null && index >= 0) { diff --git a/core/java/android/service/autofill/FillRequest.java b/core/java/android/service/autofill/FillRequest.java index 327cda3360bb..b4010a4eefda 100644 --- a/core/java/android/service/autofill/FillRequest.java +++ b/core/java/android/service/autofill/FillRequest.java @@ -453,7 +453,7 @@ public final class FillRequest implements Parcelable { byte flg = in.readByte(); int id = in.readInt(); List<FillContext> fillContexts = new ArrayList<>(); - in.readParcelableList(fillContexts, FillContext.class.getClassLoader()); + in.readParcelableList(fillContexts, FillContext.class.getClassLoader(), android.service.autofill.FillContext.class); Bundle clientState = (flg & 0x4) == 0 ? null : in.readBundle(); int flags = in.readInt(); InlineSuggestionsRequest inlineSuggestionsRequest = (flg & 0x10) == 0 ? null : (InlineSuggestionsRequest) in.readTypedObject(InlineSuggestionsRequest.CREATOR); diff --git a/core/java/android/service/contentsuggestions/ContentSuggestionsService.java b/core/java/android/service/contentsuggestions/ContentSuggestionsService.java index 50efbac76f48..0b4739ea1afc 100644 --- a/core/java/android/service/contentsuggestions/ContentSuggestionsService.java +++ b/core/java/android/service/contentsuggestions/ContentSuggestionsService.java @@ -72,7 +72,7 @@ public abstract class ContentSuggestionsService extends Service { Bitmap wrappedBuffer = null; if (imageContextRequestExtras.containsKey(ContentSuggestionsManager.EXTRA_BITMAP)) { wrappedBuffer = imageContextRequestExtras.getParcelable( - ContentSuggestionsManager.EXTRA_BITMAP); + ContentSuggestionsManager.EXTRA_BITMAP, android.graphics.Bitmap.class); } else { if (contextImage != null) { ColorSpace colorSpace = null; diff --git a/core/java/android/service/controls/templates/ThumbnailTemplate.java b/core/java/android/service/controls/templates/ThumbnailTemplate.java index a7c481e38e55..e058b76736fc 100644 --- a/core/java/android/service/controls/templates/ThumbnailTemplate.java +++ b/core/java/android/service/controls/templates/ThumbnailTemplate.java @@ -65,7 +65,7 @@ public final class ThumbnailTemplate extends ControlTemplate { ThumbnailTemplate(Bundle b) { super(b); mActive = b.getBoolean(KEY_ACTIVE); - mThumbnail = b.getParcelable(KEY_ICON); + mThumbnail = b.getParcelable(KEY_ICON, android.graphics.drawable.Icon.class); mContentDescription = b.getCharSequence(KEY_CONTENT_DESCRIPTION, ""); } diff --git a/core/java/android/service/controls/templates/ToggleRangeTemplate.java b/core/java/android/service/controls/templates/ToggleRangeTemplate.java index cd6a2fc45612..4ad42a38200b 100644 --- a/core/java/android/service/controls/templates/ToggleRangeTemplate.java +++ b/core/java/android/service/controls/templates/ToggleRangeTemplate.java @@ -43,7 +43,7 @@ public final class ToggleRangeTemplate extends ControlTemplate { */ ToggleRangeTemplate(@NonNull Bundle b) { super(b); - mControlButton = b.getParcelable(KEY_BUTTON); + mControlButton = b.getParcelable(KEY_BUTTON, android.service.controls.templates.ControlButton.class); mRangeTemplate = new RangeTemplate(b.getBundle(KEY_RANGE)); } diff --git a/core/java/android/service/controls/templates/ToggleTemplate.java b/core/java/android/service/controls/templates/ToggleTemplate.java index e4aa6b0d6cec..687e75064a9a 100644 --- a/core/java/android/service/controls/templates/ToggleTemplate.java +++ b/core/java/android/service/controls/templates/ToggleTemplate.java @@ -53,7 +53,7 @@ public final class ToggleTemplate extends ControlTemplate { */ ToggleTemplate(Bundle b) { super(b); - mButton = b.getParcelable(KEY_BUTTON); + mButton = b.getParcelable(KEY_BUTTON, android.service.controls.templates.ControlButton.class); } public boolean isChecked() { diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java index 2d461c6cf92e..b0c5d8387d74 100644 --- a/core/java/android/service/dreams/DreamService.java +++ b/core/java/android/service/dreams/DreamService.java @@ -993,7 +993,7 @@ public class DreamService extends Service implements Window.Callback { if (!mWindowless) { mOverlayConnection.bind( /* context= */ this, - intent.getParcelableExtra(EXTRA_DREAM_OVERLAY_COMPONENT), + intent.getParcelableExtra(EXTRA_DREAM_OVERLAY_COMPONENT, android.content.ComponentName.class), new ComponentName(this, getClass())); } diff --git a/core/java/android/service/games/GameSessionTrampolineActivity.java b/core/java/android/service/games/GameSessionTrampolineActivity.java index b23791842284..93f19d5bd41c 100644 --- a/core/java/android/service/games/GameSessionTrampolineActivity.java +++ b/core/java/android/service/games/GameSessionTrampolineActivity.java @@ -94,7 +94,7 @@ public final class GameSessionTrampolineActivity extends Activity { try { startActivityAsCaller( - getIntent().getParcelableExtra(INTENT_KEY), + getIntent().getParcelableExtra(INTENT_KEY, android.content.Intent.class), getIntent().getBundleExtra(OPTIONS_KEY), false, getUserId(), @@ -102,7 +102,7 @@ public final class GameSessionTrampolineActivity extends Activity { } catch (Exception e) { Slog.w(TAG, "Unable to launch activity from game session"); AndroidFuture<GameSessionActivityResult> future = getIntent().getParcelableExtra( - FUTURE_KEY); + FUTURE_KEY, com.android.internal.infra.AndroidFuture.class); future.completeExceptionally(e); finish(); overridePendingTransition(0, 0); @@ -123,7 +123,7 @@ public final class GameSessionTrampolineActivity extends Activity { } AndroidFuture<GameSessionActivityResult> future = getIntent().getParcelableExtra( - FUTURE_KEY); + FUTURE_KEY, com.android.internal.infra.AndroidFuture.class); future.complete(new GameSessionActivityResult(resultCode, data)); finish(); overridePendingTransition(0, 0); diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index 65f0824a9b78..02176b0c123e 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -1379,7 +1379,7 @@ public abstract class NotificationListenerService extends Service { private void maybePopulatePeople(Notification notification) { if (getContext().getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.P) { ArrayList<Person> people = notification.extras.getParcelableArrayList( - Notification.EXTRA_PEOPLE_LIST); + Notification.EXTRA_PEOPLE_LIST, android.app.Person.class); if (people != null && people.isEmpty()) { int size = people.size(); String[] peopleArray = new String[size]; diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java index 66188cd19721..e2c84dcbb908 100644 --- a/core/java/android/service/notification/StatusBarNotification.java +++ b/core/java/android/service/notification/StatusBarNotification.java @@ -500,7 +500,7 @@ public class StatusBarNotification implements Parcelable { template.hashCode()); } ArrayList<Person> people = getNotification().extras.getParcelableArrayList( - Notification.EXTRA_PEOPLE_LIST); + Notification.EXTRA_PEOPLE_LIST, android.app.Person.class); if (people != null && !people.isEmpty()) { logMaker.addTaggedData(MetricsEvent.FIELD_NOTIFICATION_PEOPLE, people.size()); } diff --git a/core/java/android/service/restrictions/RestrictionsReceiver.java b/core/java/android/service/restrictions/RestrictionsReceiver.java index e8d481a65b31..badd0c207bb9 100644 --- a/core/java/android/service/restrictions/RestrictionsReceiver.java +++ b/core/java/android/service/restrictions/RestrictionsReceiver.java @@ -77,7 +77,7 @@ public abstract class RestrictionsReceiver extends BroadcastReceiver { String requestType = intent.getStringExtra(RestrictionsManager.EXTRA_REQUEST_TYPE); String requestId = intent.getStringExtra(RestrictionsManager.EXTRA_REQUEST_ID); PersistableBundle request = (PersistableBundle) - intent.getParcelableExtra(RestrictionsManager.EXTRA_REQUEST_BUNDLE); + intent.getParcelableExtra(RestrictionsManager.EXTRA_REQUEST_BUNDLE, android.os.PersistableBundle.class); onRequestPermission(context, packageName, requestType, requestId, request); } } diff --git a/core/java/android/service/trust/TrustAgentService.java b/core/java/android/service/trust/TrustAgentService.java index 559313a30dfa..ad4f9f718f7f 100644 --- a/core/java/android/service/trust/TrustAgentService.java +++ b/core/java/android/service/trust/TrustAgentService.java @@ -257,7 +257,7 @@ public class TrustAgentService extends Service { Bundle data = msg.getData(); byte[] token = data.getByteArray(EXTRA_TOKEN); long handle = data.getLong(EXTRA_TOKEN_HANDLE); - UserHandle user = (UserHandle) data.getParcelable(EXTRA_USER_HANDLE); + UserHandle user = (UserHandle) data.getParcelable(EXTRA_USER_HANDLE, android.os.UserHandle.class); onEscrowTokenAdded(token, handle, user); break; } diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java index 7d17093b2707..42500b4cfcff 100644 --- a/core/java/android/service/voice/VoiceInteractionSession.java +++ b/core/java/android/service/voice/VoiceInteractionSession.java @@ -1547,7 +1547,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall list = Collections.emptyList(); } else { final ParceledListSlice<DirectAction> pls = result.getParcelable( - DirectAction.KEY_ACTIONS_LIST); + DirectAction.KEY_ACTIONS_LIST, android.content.pm.ParceledListSlice.class); if (pls != null) { final List<DirectAction> receivedList = pls.getList(); list = (receivedList != null) ? receivedList : Collections.emptyList(); diff --git a/core/java/android/speech/AlternativeSpans.java b/core/java/android/speech/AlternativeSpans.java index 0de8c3e65c48..2277e55a7836 100644 --- a/core/java/android/speech/AlternativeSpans.java +++ b/core/java/android/speech/AlternativeSpans.java @@ -140,7 +140,7 @@ public final class AlternativeSpans implements Parcelable { // static FieldType unparcelFieldName(Parcel in) { ... } List<AlternativeSpan> spans = new ArrayList<>(); - in.readParcelableList(spans, AlternativeSpan.class.getClassLoader()); + in.readParcelableList(spans, AlternativeSpan.class.getClassLoader(), android.speech.AlternativeSpan.class); this.mSpans = spans; com.android.internal.util.AnnotationValidations.validate( diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java index 26c831428f1c..a00d8cfb36f7 100644 --- a/core/java/android/speech/tts/TextToSpeechService.java +++ b/core/java/android/speech/tts/TextToSpeechService.java @@ -742,7 +742,7 @@ public abstract class TextToSpeechService extends Service { AudioAttributes audioAttributes = (AudioAttributes) paramsBundle.getParcelable( - Engine.KEY_PARAM_AUDIO_ATTRIBUTES); + Engine.KEY_PARAM_AUDIO_ATTRIBUTES, android.media.AudioAttributes.class); if (audioAttributes == null) { int streamType = paramsBundle.getInt( Engine.KEY_PARAM_STREAM, Engine.DEFAULT_STREAM); diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java index 23e1505e1a4c..a6f63e859049 100644 --- a/core/java/android/view/AccessibilityInteractionController.java +++ b/core/java/android/view/AccessibilityInteractionController.java @@ -21,6 +21,7 @@ import static android.view.accessibility.AccessibilityNodeInfo.ACTION_ARGUMENT_A import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_REQUESTED_KEY; import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY; +import android.annotation.NonNull; import android.graphics.Matrix; import android.graphics.Rect; import android.graphics.RectF; @@ -959,29 +960,6 @@ public final class AccessibilityInteractionController { && mViewRootImpl.mAttachInfo.mLeashedParentAccessibilityViewId == View.NO_ID); } - private void applyAppScaleAndMagnificationSpecIfNeeded(AccessibilityNodeInfo info, - MagnificationSpec spec) { - if (info == null) { - return; - } - - final float applicationScale = mViewRootImpl.mAttachInfo.mApplicationScale; - if (!shouldApplyAppScaleAndMagnificationSpec(applicationScale, spec)) { - return; - } - Rect boundsInParent = mTempRect; - - info.getBoundsInParent(boundsInParent); - if (applicationScale != 1.0f) { - boundsInParent.scale(applicationScale); - } - if (spec != null) { - boundsInParent.scale(spec.scale); - // boundsInParent must not be offset. - } - info.setBoundsInParent(boundsInParent); - } - private boolean shouldApplyAppScaleAndMagnificationSpec(float appScale, MagnificationSpec spec) { return (appScale != 1.0f || (spec != null && !spec.isNop())); @@ -1002,7 +980,6 @@ public final class AccessibilityInteractionController { // Transform view bounds from window coordinates to screen coordinates. transformBoundsWithScreenMatrix(info, matrixValues); adjustIsVisibleToUserIfNeeded(info, interactiveRegion, spec); - applyAppScaleAndMagnificationSpecIfNeeded(info, spec); } @@ -1042,10 +1019,7 @@ public final class AccessibilityInteractionController { return; } transformMatrix.mapRect(transformedBounds); - // Offset 0.5f to round after casting. - transformedBounds.offset(0.5f, 0.5f); - boundInScreen.set((int) (transformedBounds.left), (int) transformedBounds.top, - (int) transformedBounds.right, (int) transformedBounds.bottom); + roundRectFToRect(transformedBounds, boundInScreen); info.setBoundsInScreen(boundInScreen); // Scale text locations if they are present if (info.hasExtras()) { @@ -1063,6 +1037,26 @@ public final class AccessibilityInteractionController { } } } + applyTransformMatrixToBoundsInParentIfNeeded(info, transformMatrix); + } + + private void applyTransformMatrixToBoundsInParentIfNeeded(AccessibilityNodeInfo info, + Matrix transformMatrix) { + final float[] screenMatrixValues = new float[9]; + transformMatrix.getValues(screenMatrixValues); + final Matrix scaleMatrix = new Matrix(); + scaleMatrix.setScale(screenMatrixValues[Matrix.MSCALE_X], + screenMatrixValues[Matrix.MSCALE_X]); + if (scaleMatrix.isIdentity()) { + return; + } + Rect boundsInParent = mTempRect; + final RectF transformedBounds = mTempRectF; + info.getBoundsInParent(boundsInParent); + transformedBounds.set(boundsInParent); + scaleMatrix.mapRect(transformedBounds); + roundRectFToRect(transformedBounds, boundsInParent); + info.setBoundsInParent(boundsInParent); } private void updateInfosForViewportAndReturnFindNodeResult(List<AccessibilityNodeInfo> infos, @@ -1213,6 +1207,12 @@ public final class AccessibilityInteractionController { return false; } + private static void roundRectFToRect(@NonNull RectF sourceRectF, @NonNull Rect outRect) { + // Offset 0.5f to round after casting. + outRect.set((int) (sourceRectF.left + 0.5), (int) (sourceRectF.top + 0.5), + (int) (sourceRectF.right + 0.5), (int) (sourceRectF.bottom + 0.5)); + } + /** * This class encapsulates a prefetching strategy for the accessibility APIs for * querying window content. It is responsible to prefetch a batch of diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 545782132099..1e9769e6270b 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -31893,7 +31893,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, RemoteCallback remoteCallback = new RemoteCallback(result -> executor.execute(() -> { - DisplayHash displayHash = result.getParcelable(EXTRA_DISPLAY_HASH); + DisplayHash displayHash = result.getParcelable(EXTRA_DISPLAY_HASH, android.view.displayhash.DisplayHash.class); int errorCode = result.getInt(EXTRA_DISPLAY_HASH_ERROR_CODE, DISPLAY_HASH_ERROR_UNKNOWN); if (displayHash != null) { diff --git a/core/java/android/view/WindowInfo.java b/core/java/android/view/WindowInfo.java index a5b8720c7dec..11d63c84d142 100644 --- a/core/java/android/view/WindowInfo.java +++ b/core/java/android/view/WindowInfo.java @@ -208,6 +208,8 @@ public class WindowInfo implements Parcelable { mTransformMatrix[i] = 0; } mMagnificationSpec.clear(); + title = null; + accessibilityIdOfAnchor = AccessibilityNodeInfo.UNDEFINED_NODE_ID; } public static final @android.annotation.NonNull Parcelable.Creator<WindowInfo> CREATOR = diff --git a/core/java/android/view/WindowLayout.java b/core/java/android/view/WindowLayout.java index 9b6b2b906e8e..0941ee8a714f 100644 --- a/core/java/android/view/WindowLayout.java +++ b/core/java/android/view/WindowLayout.java @@ -16,8 +16,6 @@ package android.view; -import static android.view.Gravity.DISPLAY_CLIP_HORIZONTAL; -import static android.view.Gravity.DISPLAY_CLIP_VERTICAL; import static android.view.InsetsState.ITYPE_IME; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR; @@ -275,17 +273,9 @@ public class WindowLayout { Gravity.applyDisplay(attrs.gravity, outDisplayFrame, outFrame); } - if (extendedByCutout && !displayCutoutSafe.contains(outFrame)) { - mTempRect.set(outFrame); - - // Move the frame into displayCutoutSafe. - final int clipFlags = DISPLAY_CLIP_VERTICAL | DISPLAY_CLIP_HORIZONTAL; - Gravity.applyDisplay(attrs.gravity & ~clipFlags, displayCutoutSafe, + if (extendedByCutout) { + extendFrameByCutout(attrs.gravity, displayCutoutSafe, outDisplayFrame, outFrame, mTempRect); - - if (mTempRect.intersect(outDisplayFrame)) { - outFrame.union(mTempRect); - } } if (DEBUG) Log.d(TAG, "computeFrames " + attrs.getTitle() @@ -301,6 +291,21 @@ public class WindowLayout { + " requestedVisibilities=" + requestedVisibilities); } + public static void extendFrameByCutout(int gravity, Rect displayCutoutSafe, + Rect displayFrame, Rect inOutFrame, Rect tempRect) { + if (displayCutoutSafe.contains(inOutFrame)) { + return; + } + tempRect.set(inOutFrame); + + // Move the frame into displayCutoutSafe. + Gravity.applyDisplay(0 /* gravity */, displayCutoutSafe, tempRect); + + if (tempRect.intersect(displayFrame)) { + inOutFrame.union(tempRect); + } + } + public static void computeSurfaceSize(WindowManager.LayoutParams attrs, Rect maxBounds, int requestedWidth, int requestedHeight, Rect winFrame, boolean dragResizing, Point outSurfaceSize) { diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java index 20cdad42b4cc..dc4ccbad27be 100644 --- a/core/java/android/view/WindowManagerImpl.java +++ b/core/java/android/view/WindowManagerImpl.java @@ -213,7 +213,7 @@ public final class WindowManagerImpl implements WindowManager { @Override public void send(int resultCode, Bundle resultData) throws RemoteException { List<KeyboardShortcutGroup> result = - resultData.getParcelableArrayList(PARCEL_KEY_SHORTCUTS_ARRAY); + resultData.getParcelableArrayList(PARCEL_KEY_SHORTCUTS_ARRAY, android.view.KeyboardShortcutGroup.class); receiver.onKeyboardShortcutsReceived(result); } }; diff --git a/core/java/android/view/accessibility/IAccessibilityManager.aidl b/core/java/android/view/accessibility/IAccessibilityManager.aidl index 418132a6e597..4fc9a077299a 100644 --- a/core/java/android/view/accessibility/IAccessibilityManager.aidl +++ b/core/java/android/view/accessibility/IAccessibilityManager.aidl @@ -63,9 +63,6 @@ interface IAccessibilityManager { void unregisterUiTestAutomationService(IAccessibilityServiceClient client); - void temporaryEnableAccessibilityStateUntilKeyguardRemoved(in ComponentName service, - boolean touchExplorationEnabled); - // Used by UiAutomation IBinder getWindowToken(int windowId, int userId); diff --git a/core/java/android/view/autofill/AutofillId.java b/core/java/android/view/autofill/AutofillId.java index ae145de21190..313dc431a5e5 100644 --- a/core/java/android/view/autofill/AutofillId.java +++ b/core/java/android/view/autofill/AutofillId.java @@ -74,6 +74,10 @@ public final class AutofillId implements Parcelable { /** @hide */ @NonNull + public static final AutofillId NO_AUTOFILL_ID = new AutofillId(0); + + /** @hide */ + @NonNull @TestApi public static AutofillId withoutSession(@NonNull AutofillId id) { final int flags = id.mFlags & ~FLAG_HAS_SESSION; diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index 6a27eb5a5d82..dbefcfb5ef17 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -944,7 +944,7 @@ public final class AutofillManager { return; } synchronized (mLock) { - mLastAutofilledData = savedInstanceState.getParcelable(LAST_AUTOFILLED_DATA_TAG); + mLastAutofilledData = savedInstanceState.getParcelable(LAST_AUTOFILLED_DATA_TAG, android.view.autofill.ParcelableMap.class); if (isActiveLocked()) { Log.w(TAG, "New session was started before onCreate()"); diff --git a/core/java/android/view/inputmethod/EditorInfo.java b/core/java/android/view/inputmethod/EditorInfo.java index 6b7a6e946d0e..949237548926 100644 --- a/core/java/android/view/inputmethod/EditorInfo.java +++ b/core/java/android/view/inputmethod/EditorInfo.java @@ -1016,6 +1016,7 @@ public class EditorInfo implements InputType, Parcelable { newEditorInfo.mInitialSurroundingText = mInitialSurroundingText; newEditorInfo.hintLocales = hintLocales; newEditorInfo.contentMimeTypes = ArrayUtils.cloneOrNull(contentMimeTypes); + newEditorInfo.targetInputMethodUser = targetInputMethodUser; return newEditorInfo; } diff --git a/core/java/android/view/inputmethod/IInputMethodManagerInvoker.java b/core/java/android/view/inputmethod/IInputMethodManagerInvoker.java new file mode 100644 index 000000000000..4b472ed18325 --- /dev/null +++ b/core/java/android/view/inputmethod/IInputMethodManagerInvoker.java @@ -0,0 +1,260 @@ +/* + * Copyright (C) 2022 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.inputmethod; + +import android.annotation.AnyThread; +import android.annotation.NonNull; +import android.annotation.UserIdInt; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.ResultReceiver; +import android.window.ImeOnBackInvokedDispatcher; + +import com.android.internal.inputmethod.DirectBootAwareness; +import com.android.internal.inputmethod.IInputMethodClient; +import com.android.internal.inputmethod.IRemoteAccessibilityInputConnection; +import com.android.internal.inputmethod.IRemoteInputConnection; +import com.android.internal.inputmethod.InputBindResult; +import com.android.internal.inputmethod.SoftInputShowHideReason; +import com.android.internal.inputmethod.StartInputFlags; +import com.android.internal.inputmethod.StartInputReason; +import com.android.internal.view.IInputMethodManager; + +import java.util.List; + +/** + * A wrapper class to invoke IPCs defined in {@link IInputMethodManager}. + */ +final class IInputMethodManagerInvoker { + @NonNull + private final IInputMethodManager mTarget; + + private IInputMethodManagerInvoker(@NonNull IInputMethodManager target) { + mTarget = target; + } + + @AnyThread + @NonNull + static IInputMethodManagerInvoker create(@NonNull IInputMethodManager imm) { + return new IInputMethodManagerInvoker(imm); + } + + @AnyThread + void addClient(IInputMethodClient client, IRemoteInputConnection fallbackInputConnection, + int untrustedDisplayId) { + try { + mTarget.addClient(client, fallbackInputConnection, untrustedDisplayId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + @AnyThread + List<InputMethodInfo> getInputMethodList(@UserIdInt int userId) { + try { + return mTarget.getInputMethodList(userId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + @AnyThread + List<InputMethodInfo> getAwareLockedInputMethodList(@UserIdInt int userId, + @DirectBootAwareness int directBootAwareness) { + try { + return mTarget.getAwareLockedInputMethodList(userId, directBootAwareness); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + @AnyThread + List<InputMethodInfo> getEnabledInputMethodList(@UserIdInt int userId) { + try { + return mTarget.getEnabledInputMethodList(userId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + @AnyThread + List<InputMethodSubtype> getEnabledInputMethodSubtypeList(String imiId, + boolean allowsImplicitlySelectedSubtypes) { + try { + return mTarget.getEnabledInputMethodSubtypeList(imiId, + allowsImplicitlySelectedSubtypes); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + @AnyThread + InputMethodSubtype getLastInputMethodSubtype() { + try { + return mTarget.getLastInputMethodSubtype(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + @AnyThread + boolean showSoftInput(IInputMethodClient client, IBinder windowToken, + int flags, ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) { + try { + return mTarget.showSoftInput(client, windowToken, flags, resultReceiver, reason); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + @AnyThread + boolean hideSoftInput(IInputMethodClient client, IBinder windowToken, + int flags, ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) { + try { + return mTarget.hideSoftInput(client, windowToken, flags, resultReceiver, reason); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + @AnyThread + InputBindResult startInputOrWindowGainedFocus(@StartInputReason int startInputReason, + IInputMethodClient client, IBinder windowToken, + @StartInputFlags int startInputFlags, + @android.view.WindowManager.LayoutParams.SoftInputModeFlags int softInputMode, + int windowFlags, EditorInfo editorInfo, IRemoteInputConnection remoteInputConnection, + IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection, + int unverifiedTargetSdkVersion, ImeOnBackInvokedDispatcher imeDispatcher) { + try { + return mTarget.startInputOrWindowGainedFocus(startInputReason, client, windowToken, + startInputFlags, softInputMode, windowFlags, editorInfo, remoteInputConnection, + remoteAccessibilityInputConnection, unverifiedTargetSdkVersion, imeDispatcher); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + @AnyThread + void showInputMethodPickerFromClient(IInputMethodClient client, int auxiliarySubtypeMode) { + try { + mTarget.showInputMethodPickerFromClient(client, auxiliarySubtypeMode); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + @AnyThread + void showInputMethodPickerFromSystem(IInputMethodClient client, int auxiliarySubtypeMode, + int displayId) { + try { + mTarget.showInputMethodPickerFromSystem(client, auxiliarySubtypeMode, displayId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + @AnyThread + void showInputMethodAndSubtypeEnablerFromClient(IInputMethodClient client, String imeId) { + try { + mTarget.showInputMethodAndSubtypeEnablerFromClient(client, imeId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + @AnyThread + boolean isInputMethodPickerShownForTest() { + try { + return mTarget.isInputMethodPickerShownForTest(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + @AnyThread + InputMethodSubtype getCurrentInputMethodSubtype() { + try { + return mTarget.getCurrentInputMethodSubtype(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + @AnyThread + void setAdditionalInputMethodSubtypes(String imeId, InputMethodSubtype[] subtypes) { + try { + mTarget.setAdditionalInputMethodSubtypes(imeId, subtypes); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + @AnyThread + int getInputMethodWindowVisibleHeight(IInputMethodClient client) { + try { + return mTarget.getInputMethodWindowVisibleHeight(client); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + @AnyThread + void reportVirtualDisplayGeometryAsync(IInputMethodClient client, int childDisplayId, + float[] matrixValues) { + try { + mTarget.reportVirtualDisplayGeometryAsync(client, childDisplayId, matrixValues); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + @AnyThread + void reportPerceptibleAsync(IBinder windowToken, boolean perceptible) { + try { + mTarget.reportPerceptibleAsync(windowToken, perceptible); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + @AnyThread + void removeImeSurfaceFromWindowAsync(IBinder windowToken) { + try { + mTarget.removeImeSurfaceFromWindowAsync(windowToken); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + @AnyThread + void startStylusHandwriting(IInputMethodClient client) { + try { + mTarget.startStylusHandwriting(client); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + @AnyThread + boolean isStylusHandwritingAvailableAsUser(@UserIdInt int userId) { + try { + return mTarget.isStylusHandwritingAvailableAsUser(userId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } +} diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 515ba6338f71..1b14110b7330 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -65,7 +65,6 @@ import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.Process; -import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ServiceManager; import android.os.ServiceManager.ServiceNotFoundException; @@ -90,6 +89,7 @@ import android.view.KeyEvent; import android.view.View; import android.view.ViewRootImpl; import android.view.WindowManager.LayoutParams.SoftInputModeFlags; +import android.view.autofill.AutofillId; import android.view.autofill.AutofillManager; import android.window.ImeOnBackInvokedDispatcher; import android.window.WindowOnBackInvokedDispatcher; @@ -394,10 +394,17 @@ public final class InputMethodManager { @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU) public static final long CLEAR_SHOW_FORCED_FLAG_WHEN_LEAVING = 214016041L; // This is a bug id. + /** + * @deprecated Use {@link #mServiceInvoker} instead. + */ + @Deprecated @UnsupportedAppUsage final IInputMethodManager mService; final Looper mMainLooper; + @NonNull + private final IInputMethodManagerInvoker mServiceInvoker; + // For scheduling work on the main thread. This also serves as our // global lock. // Remark on @UnsupportedAppUsage: there were context leaks on old versions @@ -636,11 +643,7 @@ public final class InputMethodManager { * @hide */ public void reportPerceptible(IBinder windowToken, boolean perceptible) { - try { - mService.reportPerceptibleAsync(windowToken, perceptible); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + mServiceInvoker.reportPerceptibleAsync(windowToken, perceptible); } private final class DelegateImpl implements @@ -737,30 +740,26 @@ public final class InputMethodManager { synchronized (mH) { // For some reason we didn't do a startInput + windowFocusGain, so // we'll just do a window focus gain and call it a day. - try { - View servedView = controller.getServedView(); - boolean nextFocusHasConnection = servedView != null && servedView == focusedView - && hasActiveConnection(focusedView); - if (DEBUG) { - Log.v(TAG, "Reporting focus gain, without startInput" - + ", nextFocusIsServedView=" + nextFocusHasConnection); - } - - final int startInputReason = nextFocusHasConnection - ? WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION - : WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION; - // ignore the result - mService.startInputOrWindowGainedFocus( - startInputReason, mClient, - focusedView.getWindowToken(), startInputFlags, softInputMode, - windowFlags, - null, - null, null, - mCurRootView.mContext.getApplicationInfo().targetSdkVersion, - mImeDispatcher); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + View servedView = controller.getServedView(); + boolean nextFocusHasConnection = servedView != null && servedView == focusedView + && hasActiveConnection(focusedView); + if (DEBUG) { + Log.v(TAG, "Reporting focus gain, without startInput" + + ", nextFocusIsServedView=" + nextFocusHasConnection); } + + final int startInputReason = nextFocusHasConnection + ? WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION + : WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION; + // ignore the result + mServiceInvoker.startInputOrWindowGainedFocus( + startInputReason, mClient, + focusedView.getWindowToken(), startInputFlags, softInputMode, + windowFlags, + null, + null, null, + mCurRootView.mContext.getApplicationInfo().targetSdkVersion, + mImeDispatcher); } } @@ -1005,7 +1004,6 @@ public final class InputMethodManager { } } } - mBindSequence = res.sequence; } startInputInner(StartInputReason.BOUND_ACCESSIBILITY_SESSION_TO_IMMS, null, 0, 0, 0); @@ -1273,9 +1271,7 @@ public final class InputMethodManager { // 1) doing so has no effect for A and 2) doing so is sufficient for B. final long identity = Binder.clearCallingIdentity(); try { - service.addClient(imm.mClient, imm.mFallbackInputConnection, displayId); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); + imm.mServiceInvoker.addClient(imm.mClient, imm.mFallbackInputConnection, displayId); } finally { Binder.restoreCallingIdentity(identity); } @@ -1313,8 +1309,9 @@ public final class InputMethodManager { return new InputMethodManager(stubInterface, displayId, looper); } - private InputMethodManager(IInputMethodManager service, int displayId, Looper looper) { - mService = service; + private InputMethodManager(@NonNull IInputMethodManager service, int displayId, Looper looper) { + mService = service; // For @UnsupportedAppUsage + mServiceInvoker = IInputMethodManagerInvoker.create(service); mMainLooper = looper; mH = new H(looper); mDisplayId = displayId; @@ -1404,14 +1401,10 @@ public final class InputMethodManager { * @return {@link List} of {@link InputMethodInfo}. */ public List<InputMethodInfo> getInputMethodList() { - try { - // We intentionally do not use UserHandle.getCallingUserId() here because for system - // services InputMethodManagerInternal.getInputMethodListAsUser() should be used - // instead. - return mService.getInputMethodList(UserHandle.myUserId()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + // We intentionally do not use UserHandle.getCallingUserId() here because for system + // services InputMethodManagerInternal.getInputMethodListAsUser() should be used + // instead. + return mServiceInvoker.getInputMethodList(UserHandle.myUserId()); } /** @@ -1445,11 +1438,7 @@ public final class InputMethodManager { } return false; } - try { - return mService.isStylusHandwritingAvailableAsUser(userId); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + return mServiceInvoker.isStylusHandwritingAvailableAsUser(userId); } /** @@ -1463,11 +1452,7 @@ public final class InputMethodManager { @RequiresPermission(INTERACT_ACROSS_USERS_FULL) @NonNull public List<InputMethodInfo> getInputMethodListAsUser(@UserIdInt int userId) { - try { - return mService.getInputMethodList(userId); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + return mServiceInvoker.getInputMethodList(userId); } /** @@ -1483,11 +1468,7 @@ public final class InputMethodManager { @NonNull public List<InputMethodInfo> getInputMethodListAsUser(@UserIdInt int userId, @DirectBootAwareness int directBootAwareness) { - try { - return mService.getAwareLockedInputMethodList(userId, directBootAwareness); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + return mServiceInvoker.getAwareLockedInputMethodList(userId, directBootAwareness); } /** @@ -1498,14 +1479,10 @@ public final class InputMethodManager { * @return {@link List} of {@link InputMethodInfo}. */ public List<InputMethodInfo> getEnabledInputMethodList() { - try { - // We intentionally do not use UserHandle.getCallingUserId() here because for system - // services InputMethodManagerInternal.getEnabledInputMethodListAsUser() should be used - // instead. - return mService.getEnabledInputMethodList(UserHandle.myUserId()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + // We intentionally do not use UserHandle.getCallingUserId() here because for system + // services InputMethodManagerInternal.getEnabledInputMethodListAsUser() should be used + // instead. + return mServiceInvoker.getEnabledInputMethodList(UserHandle.myUserId()); } /** @@ -1517,11 +1494,7 @@ public final class InputMethodManager { */ @RequiresPermission(INTERACT_ACROSS_USERS_FULL) public List<InputMethodInfo> getEnabledInputMethodListAsUser(@UserIdInt int userId) { - try { - return mService.getEnabledInputMethodList(userId); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + return mServiceInvoker.getEnabledInputMethodList(userId); } /** @@ -1536,13 +1509,9 @@ public final class InputMethodManager { */ public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(InputMethodInfo imi, boolean allowsImplicitlySelectedSubtypes) { - try { - return mService.getEnabledInputMethodSubtypeList( - imi == null ? null : imi.getId(), - allowsImplicitlySelectedSubtypes); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + return mServiceInvoker.getEnabledInputMethodSubtypeList( + imi == null ? null : imi.getId(), + allowsImplicitlySelectedSubtypes); } /** @@ -1905,18 +1874,14 @@ public final class InputMethodManager { // Makes sure to call ImeInsetsSourceConsumer#onShowRequested on the UI thread. // TODO(b/229426865): call WindowInsetsController#show instead. mH.executeOrSendMessage(Message.obtain(mH, MSG_ON_SHOW_REQUESTED)); - try { - Log.d(TAG, "showSoftInput() view=" + view + " flags=" + flags + " reason=" - + InputMethodDebug.softInputDisplayReasonToString(reason)); - return mService.showSoftInput( - mClient, - view.getWindowToken(), - flags, - resultReceiver, - reason); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + Log.d(TAG, "showSoftInput() view=" + view + " flags=" + flags + " reason=" + + InputMethodDebug.softInputDisplayReasonToString(reason)); + return mServiceInvoker.showSoftInput( + mClient, + view.getWindowToken(), + flags, + resultReceiver, + reason); } } @@ -1932,26 +1897,22 @@ public final class InputMethodManager { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768499) public void showSoftInputUnchecked(int flags, ResultReceiver resultReceiver) { synchronized (mH) { - try { - Log.w(TAG, "showSoftInputUnchecked() is a hidden method, which will be" - + " removed soon. If you are using androidx.appcompat.widget.SearchView," - + " please update to version 26.0 or newer version."); - if (mCurRootView == null || mCurRootView.getView() == null) { - Log.w(TAG, "No current root view, ignoring showSoftInputUnchecked()"); - return; - } - // Makes sure to call ImeInsetsSourceConsumer#onShowRequested on the UI thread. - // TODO(b/229426865): call WindowInsetsController#show instead. - mH.executeOrSendMessage(Message.obtain(mH, MSG_ON_SHOW_REQUESTED)); - mService.showSoftInput( - mClient, - mCurRootView.getView().getWindowToken(), - flags, - resultReceiver, - SoftInputShowHideReason.SHOW_SOFT_INPUT); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + Log.w(TAG, "showSoftInputUnchecked() is a hidden method, which will be" + + " removed soon. If you are using androidx.appcompat.widget.SearchView," + + " please update to version 26.0 or newer version."); + if (mCurRootView == null || mCurRootView.getView() == null) { + Log.w(TAG, "No current root view, ignoring showSoftInputUnchecked()"); + return; } + // Makes sure to call ImeInsetsSourceConsumer#onShowRequested on the UI thread. + // TODO(b/229426865): call WindowInsetsController#show instead. + mH.executeOrSendMessage(Message.obtain(mH, MSG_ON_SHOW_REQUESTED)); + mServiceInvoker.showSoftInput( + mClient, + mCurRootView.getView().getWindowToken(), + flags, + resultReceiver, + SoftInputShowHideReason.SHOW_SOFT_INPUT); } } @@ -2026,11 +1987,8 @@ public final class InputMethodManager { return false; } - try { - return mService.hideSoftInput(mClient, windowToken, flags, resultReceiver, reason); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + return mServiceInvoker.hideSoftInput(mClient, windowToken, flags, resultReceiver, + reason); } } @@ -2087,13 +2045,9 @@ public final class InputMethodManager { mDisplayId); } - try { - mService.startStylusHandwriting(mClient); - // TODO(b/210039666): do we need any extra work for supporting non-native - // UI toolkits? - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + mServiceInvoker.startStylusHandwriting(mClient); + // TODO(b/210039666): do we need any extra work for supporting non-native + // UI toolkits? } } @@ -2339,6 +2293,14 @@ public final class InputMethodManager { InputConnection ic = view.onCreateInputConnection(tba); if (DEBUG) Log.v(TAG, "Starting input: tba=" + tba + " ic=" + ic); + // Clear autofill and field ids if a connection could not be established. + // This ensures that even disconnected EditorInfos have well-defined attributes, + // making them consistently and straightforwardly comparable. + if (ic == null) { + tba.autofillId = AutofillId.NO_AUTOFILL_ID; + tba.fieldId = 0; + } + final Handler icHandler; InputBindResult res = null; synchronized (mH) { @@ -2376,7 +2338,7 @@ public final class InputMethodManager { mServedInputConnection = null; mServedInputConnectionHandler = null; } - RemoteInputConnectionImpl servedInputConnection; + final RemoteInputConnectionImpl servedInputConnection; if (ic != null) { mCursorSelStart = tba.initialSelStart; mCursorSelEnd = tba.initialSelEnd; @@ -2408,17 +2370,13 @@ public final class InputMethodManager { + ic + " tba=" + tba + " startInputFlags=" + InputMethodDebug.startInputFlagsToString(startInputFlags)); } - try { - res = mService.startInputOrWindowGainedFocus( - startInputReason, mClient, windowGainingFocus, startInputFlags, - softInputMode, windowFlags, tba, servedInputConnection, - servedInputConnection == null ? null - : servedInputConnection.asIRemoteAccessibilityInputConnection(), - view.getContext().getApplicationInfo().targetSdkVersion, - mImeDispatcher); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + res = mServiceInvoker.startInputOrWindowGainedFocus( + startInputReason, mClient, windowGainingFocus, startInputFlags, + softInputMode, windowFlags, tba, servedInputConnection, + servedInputConnection == null ? null + : servedInputConnection.asIRemoteAccessibilityInputConnection(), + view.getContext().getApplicationInfo().targetSdkVersion, + mImeDispatcher); if (DEBUG) Log.v(TAG, "Starting input: Bind result=" + res); if (res == null) { Log.wtf(TAG, "startInputOrWindowGainedFocus must not return" @@ -2545,16 +2503,12 @@ public final class InputMethodManager { Log.w(TAG, "No current root view, ignoring closeCurrentInput()"); return; } - try { - mService.hideSoftInput( - mClient, - mCurRootView.getView().getWindowToken(), - HIDE_NOT_ALWAYS, - null, - SoftInputShowHideReason.HIDE_SOFT_INPUT); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + mServiceInvoker.hideSoftInput( + mClient, + mCurRootView.getView().getWindowToken(), + HIDE_NOT_ALWAYS, + null, + SoftInputShowHideReason.HIDE_SOFT_INPUT); } } @@ -2625,13 +2579,9 @@ public final class InputMethodManager { synchronized (mH) { if (isImeSessionAvailableLocked() && mCurRootView != null && mCurRootView.getWindowToken() == windowToken) { - try { - mService.hideSoftInput(mClient, windowToken, 0 /* flags */, - null /* resultReceiver */, - SoftInputShowHideReason.HIDE_SOFT_INPUT_BY_INSETS_API); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + mServiceInvoker.hideSoftInput(mClient, windowToken, 0 /* flags */, + null /* resultReceiver */, + SoftInputShowHideReason.HIDE_SOFT_INPUT_BY_INSETS_API); } } } @@ -2643,11 +2593,7 @@ public final class InputMethodManager { */ public void removeImeSurface(IBinder windowToken) { synchronized (mH) { - try { - mService.removeImeSurfaceFromWindowAsync(windowToken); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + mServiceInvoker.removeImeSurfaceFromWindowAsync(windowToken); } } @@ -3248,19 +3194,11 @@ public final class InputMethodManager { final int mode = showAuxiliarySubtypes ? SHOW_IM_PICKER_MODE_INCLUDE_AUXILIARY_SUBTYPES : SHOW_IM_PICKER_MODE_EXCLUDE_AUXILIARY_SUBTYPES; - try { - mService.showInputMethodPickerFromSystem(mClient, mode, displayId); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + mServiceInvoker.showInputMethodPickerFromSystem(mClient, mode, displayId); } private void showInputMethodPickerLocked() { - try { - mService.showInputMethodPickerFromClient(mClient, SHOW_IM_PICKER_MODE_AUTO); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + mServiceInvoker.showInputMethodPickerFromClient(mClient, SHOW_IM_PICKER_MODE_AUTO); } /** @@ -3276,11 +3214,7 @@ public final class InputMethodManager { */ @TestApi public boolean isInputMethodPickerShown() { - try { - return mService.isInputMethodPickerShownForTest(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + return mServiceInvoker.isInputMethodPickerShownForTest(); } /** @@ -3290,11 +3224,7 @@ public final class InputMethodManager { * subtypes of all input methods will be shown. */ public void showInputMethodAndSubtypeEnabler(String imiId) { - try { - mService.showInputMethodAndSubtypeEnablerFromClient(mClient, imiId); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + mServiceInvoker.showInputMethodAndSubtypeEnablerFromClient(mClient, imiId); } /** @@ -3303,11 +3233,7 @@ public final class InputMethodManager { * have any input method subtype. */ public InputMethodSubtype getCurrentInputMethodSubtype() { - try { - return mService.getCurrentInputMethodSubtype(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + return mServiceInvoker.getCurrentInputMethodSubtype(); } /** @@ -3351,12 +3277,8 @@ public final class InputMethodManager { // Null or invalid IME ID format. return false; } - final List<InputMethodSubtype> enabledSubtypes; - try { - enabledSubtypes = mService.getEnabledInputMethodSubtypeList(imeId, true); - } catch (RemoteException e) { - return false; - } + final List<InputMethodSubtype> enabledSubtypes = + mServiceInvoker.getEnabledInputMethodSubtypeList(imeId, true); final int numSubtypes = enabledSubtypes.size(); for (int i = 0; i < numSubtypes; ++i) { final InputMethodSubtype enabledSubtype = enabledSubtypes.get(i); @@ -3421,11 +3343,7 @@ public final class InputMethodManager { @UnsupportedAppUsage(trackingBug = 204906124, maxTargetSdk = Build.VERSION_CODES.TIRAMISU, publicAlternatives = "Use {@link android.view.WindowInsets} instead") public int getInputMethodWindowVisibleHeight() { - try { - return mService.getInputMethodWindowVisibleHeight(mClient); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + return mServiceInvoker.getInputMethodWindowVisibleHeight(mClient); } /** @@ -3438,18 +3356,14 @@ public final class InputMethodManager { * @hide */ public void reportVirtualDisplayGeometry(int childDisplayId, @Nullable Matrix matrix) { - try { - final float[] matrixValues; - if (matrix == null) { - matrixValues = null; - } else { - matrixValues = new float[9]; - matrix.getValues(matrixValues); - } - mService.reportVirtualDisplayGeometryAsync(mClient, childDisplayId, matrixValues); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + final float[] matrixValues; + if (matrix == null) { + matrixValues = null; + } else { + matrixValues = new float[9]; + matrix.getValues(matrixValues); } + mServiceInvoker.reportVirtualDisplayGeometryAsync(mClient, childDisplayId, matrixValues); } /** @@ -3553,19 +3467,11 @@ public final class InputMethodManager { */ @Deprecated public void setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes) { - try { - mService.setAdditionalInputMethodSubtypes(imiId, subtypes); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + mServiceInvoker.setAdditionalInputMethodSubtypes(imiId, subtypes); } public InputMethodSubtype getLastInputMethodSubtype() { - try { - return mService.getLastInputMethodSubtype(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + return mServiceInvoker.getLastInputMethodSubtype(); } /** diff --git a/core/java/android/view/selectiontoolbar/ShowInfo.java b/core/java/android/view/selectiontoolbar/ShowInfo.java index 594b6bc7400a..d9adef2c920b 100644 --- a/core/java/android/view/selectiontoolbar/ShowInfo.java +++ b/core/java/android/view/selectiontoolbar/ShowInfo.java @@ -284,7 +284,7 @@ public final class ShowInfo implements Parcelable { boolean layoutRequired = (flg & 0x2) != 0; long widgetToken = in.readLong(); List<ToolbarMenuItem> menuItems = new java.util.ArrayList<>(); - in.readParcelableList(menuItems, ToolbarMenuItem.class.getClassLoader()); + in.readParcelableList(menuItems, ToolbarMenuItem.class.getClassLoader(), android.view.selectiontoolbar.ToolbarMenuItem.class); Rect contentRect = (Rect) in.readTypedObject(Rect.CREATOR); int suggestedWidth = in.readInt(); Rect viewPortOnScreen = (Rect) in.readTypedObject(Rect.CREATOR); diff --git a/core/java/android/view/textclassifier/ExtrasUtils.java b/core/java/android/view/textclassifier/ExtrasUtils.java index 9e2b6427eaea..ecb838c13112 100644 --- a/core/java/android/view/textclassifier/ExtrasUtils.java +++ b/core/java/android/view/textclassifier/ExtrasUtils.java @@ -58,7 +58,7 @@ public final class ExtrasUtils { */ @Nullable public static Intent getActionIntent(Bundle container) { - return container.getParcelable(ACTION_INTENT); + return container.getParcelable(ACTION_INTENT, android.content.Intent.class); } /** @@ -69,7 +69,7 @@ public final class ExtrasUtils { if (classification == null) { return null; } - return classification.getExtras().getParcelableArrayList(ACTIONS_INTENTS); + return classification.getExtras().getParcelableArrayList(ACTIONS_INTENTS, android.content.Intent.class); } /** diff --git a/core/java/android/view/translation/TranslationManager.java b/core/java/android/view/translation/TranslationManager.java index db1c606bc99b..55c0726f259a 100644 --- a/core/java/android/view/translation/TranslationManager.java +++ b/core/java/android/view/translation/TranslationManager.java @@ -246,7 +246,7 @@ public final class TranslationManager { return Collections.emptySet(); } ParceledListSlice<TranslationCapability> listSlice = - result.bundle.getParcelable(EXTRA_CAPABILITIES); + result.bundle.getParcelable(EXTRA_CAPABILITIES, android.content.pm.ParceledListSlice.class); ArraySet<TranslationCapability> capabilities = new ArraySet<>(listSlice == null ? null : listSlice.getList()); return capabilities; @@ -466,7 +466,7 @@ public final class TranslationManager { private void onTranslationCapabilityUpdate(Bundle bundle) { TranslationCapability capability = - (TranslationCapability) bundle.getParcelable(EXTRA_CAPABILITIES); + (TranslationCapability) bundle.getParcelable(EXTRA_CAPABILITIES, android.view.translation.TranslationCapability.class); mListener.accept(capability); } } diff --git a/core/java/android/window/TaskFragmentOrganizer.java b/core/java/android/window/TaskFragmentOrganizer.java index 2ef49c3e2aac..68c934f6f0a6 100644 --- a/core/java/android/window/TaskFragmentOrganizer.java +++ b/core/java/android/window/TaskFragmentOrganizer.java @@ -220,7 +220,7 @@ public class TaskFragmentOrganizer extends WindowOrganizer { @NonNull IBinder errorCallbackToken, @NonNull Bundle exceptionBundle) { mExecutor.execute(() -> TaskFragmentOrganizer.this.onTaskFragmentError( errorCallbackToken, - (Throwable) exceptionBundle.getSerializable(KEY_ERROR_CALLBACK_EXCEPTION))); + (Throwable) exceptionBundle.getSerializable(KEY_ERROR_CALLBACK_EXCEPTION, java.lang.Throwable.class))); } @Override diff --git a/core/java/com/android/internal/app/BlockedAppStreamingActivity.java b/core/java/com/android/internal/app/BlockedAppStreamingActivity.java index ca111a49235e..d35f66519737 100644 --- a/core/java/com/android/internal/app/BlockedAppStreamingActivity.java +++ b/core/java/com/android/internal/app/BlockedAppStreamingActivity.java @@ -44,7 +44,7 @@ public class BlockedAppStreamingActivity extends AlertActivity { Intent intent = getIntent(); CharSequence appLabel = null; - ActivityInfo activityInfo = intent.getParcelableExtra(EXTRA_BLOCKED_ACTIVITY_INFO); + ActivityInfo activityInfo = intent.getParcelableExtra(EXTRA_BLOCKED_ACTIVITY_INFO, android.content.pm.ActivityInfo.class); if (activityInfo != null) { appLabel = activityInfo.loadLabel(getPackageManager()); } diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 819a8c589064..436c0652a206 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -607,9 +607,9 @@ public class ChooserActivity extends ResolverActivity implements mReferrerFillInIntent = new Intent().putExtra(Intent.EXTRA_REFERRER, getReferrer()); mChosenComponentSender = intent.getParcelableExtra( - Intent.EXTRA_CHOSEN_COMPONENT_INTENT_SENDER); + Intent.EXTRA_CHOSEN_COMPONENT_INTENT_SENDER, android.content.IntentSender.class); mRefinementIntentSender = intent.getParcelableExtra( - Intent.EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER); + Intent.EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER, android.content.IntentSender.class); setSafeForwardingMode(true); mPinnedSharedPrefs = getPinnedSharedPrefs(this); @@ -943,7 +943,7 @@ public class ChooserActivity extends ResolverActivity implements ClipData clipData = null; if (Intent.ACTION_SEND.equals(action)) { String extraText = targetIntent.getStringExtra(Intent.EXTRA_TEXT); - Uri extraStream = targetIntent.getParcelableExtra(Intent.EXTRA_STREAM); + Uri extraStream = targetIntent.getParcelableExtra(Intent.EXTRA_STREAM, android.net.Uri.class); if (extraText != null) { clipData = ClipData.newPlainText(null, extraText); @@ -955,7 +955,7 @@ public class ChooserActivity extends ResolverActivity implements } } else if (Intent.ACTION_SEND_MULTIPLE.equals(action)) { final ArrayList<Uri> streams = targetIntent.getParcelableArrayListExtra( - Intent.EXTRA_STREAM); + Intent.EXTRA_STREAM, android.net.Uri.class); clipData = ClipData.newUri(getContentResolver(), null, streams.get(0)); for (int i = 1; i < streams.size(); i++) { clipData.addItem(getContentResolver(), new ClipData.Item(streams.get(i))); @@ -1090,7 +1090,7 @@ public class ChooserActivity extends ResolverActivity implements String originalAction = originalIntent.getAction(); if (Intent.ACTION_SEND.equals(originalAction)) { if (resolveIntent.getData() == null) { - Uri uri = resolveIntent.getParcelableExtra(Intent.EXTRA_STREAM); + Uri uri = resolveIntent.getParcelableExtra(Intent.EXTRA_STREAM, android.net.Uri.class); if (uri != null) { String mimeType = getContentResolver().getType(uri); resolveIntent.setDataAndType(uri, mimeType); @@ -1335,14 +1335,14 @@ public class ChooserActivity extends ResolverActivity implements String action = targetIntent.getAction(); if (Intent.ACTION_SEND.equals(action)) { - Uri uri = targetIntent.getParcelableExtra(Intent.EXTRA_STREAM); + Uri uri = targetIntent.getParcelableExtra(Intent.EXTRA_STREAM, android.net.Uri.class); imagePreview.findViewById(R.id.content_preview_image_1_large) .setTransitionName(ChooserActivity.FIRST_IMAGE_PREVIEW_TRANSITION_NAME); mPreviewCoord.loadUriIntoView(R.id.content_preview_image_1_large, uri, 0); } else { ContentResolver resolver = getContentResolver(); - List<Uri> uris = targetIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); + List<Uri> uris = targetIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM, android.net.Uri.class); List<Uri> imageUris = new ArrayList<>(); for (Uri uri : uris) { if (isImageType(resolver.getType(uri))) { @@ -1454,10 +1454,10 @@ public class ChooserActivity extends ResolverActivity implements String action = targetIntent.getAction(); if (Intent.ACTION_SEND.equals(action)) { - Uri uri = targetIntent.getParcelableExtra(Intent.EXTRA_STREAM); + Uri uri = targetIntent.getParcelableExtra(Intent.EXTRA_STREAM, android.net.Uri.class); loadFileUriIntoView(uri, contentPreviewLayout); } else { - List<Uri> uris = targetIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); + List<Uri> uris = targetIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM, android.net.Uri.class); int uriCount = uris.size(); if (uriCount == 0) { @@ -1541,10 +1541,10 @@ public class ChooserActivity extends ResolverActivity implements private int findPreferredContentPreview(Intent targetIntent, ContentResolver resolver) { String action = targetIntent.getAction(); if (Intent.ACTION_SEND.equals(action)) { - Uri uri = targetIntent.getParcelableExtra(Intent.EXTRA_STREAM); + Uri uri = targetIntent.getParcelableExtra(Intent.EXTRA_STREAM, android.net.Uri.class); return findPreferredContentPreview(uri, resolver); } else if (Intent.ACTION_SEND_MULTIPLE.equals(action)) { - List<Uri> uris = targetIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); + List<Uri> uris = targetIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM, android.net.Uri.class); if (uris == null || uris.isEmpty()) { return CONTENT_PREVIEW_TEXT; } @@ -1914,12 +1914,12 @@ public class ChooserActivity extends ResolverActivity implements IntentFilter intentFilter = new IntentFilter(intent.getAction(), intent.getType()); List<Uri> contentUris = new ArrayList<>(); if (Intent.ACTION_SEND.equals(intent.getAction())) { - Uri uri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM); + Uri uri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM, android.net.Uri.class); if (uri != null) { contentUris.add(uri); } } else { - List<Uri> uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); + List<Uri> uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM, android.net.Uri.class); if (uris != null) { contentUris.addAll(uris); } diff --git a/core/java/com/android/internal/app/ConfirmUserCreationActivity.java b/core/java/com/android/internal/app/ConfirmUserCreationActivity.java index ee4d46dbbbd3..8833512c2217 100644 --- a/core/java/com/android/internal/app/ConfirmUserCreationActivity.java +++ b/core/java/com/android/internal/app/ConfirmUserCreationActivity.java @@ -62,7 +62,7 @@ public class ConfirmUserCreationActivity extends AlertActivity mAccountName = intent.getStringExtra(UserManager.EXTRA_USER_ACCOUNT_NAME); mAccountType = intent.getStringExtra(UserManager.EXTRA_USER_ACCOUNT_TYPE); mAccountOptions = (PersistableBundle) - intent.getParcelableExtra(UserManager.EXTRA_USER_ACCOUNT_OPTIONS); + intent.getParcelableExtra(UserManager.EXTRA_USER_ACCOUNT_OPTIONS, android.os.PersistableBundle.class); mUserManager = getSystemService(UserManager.class); diff --git a/core/java/com/android/internal/app/HarmfulAppWarningActivity.java b/core/java/com/android/internal/app/HarmfulAppWarningActivity.java index 33209e110123..c19196f46d27 100644 --- a/core/java/com/android/internal/app/HarmfulAppWarningActivity.java +++ b/core/java/com/android/internal/app/HarmfulAppWarningActivity.java @@ -54,7 +54,7 @@ public class HarmfulAppWarningActivity extends AlertActivity implements getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); final Intent intent = getIntent(); mPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME); - mTarget = intent.getParcelableExtra(Intent.EXTRA_INTENT); + mTarget = intent.getParcelableExtra(Intent.EXTRA_INTENT, android.content.IntentSender.class); mHarmfulAppWarning = intent.getStringExtra(EXTRA_HARMFUL_APP_WARNING); if (mPackageName == null || mTarget == null || mHarmfulAppWarning == null) { @@ -107,7 +107,7 @@ public class HarmfulAppWarningActivity extends AlertActivity implements case DialogInterface.BUTTON_NEGATIVE: getPackageManager().setHarmfulAppWarning(mPackageName, null /*warning*/); - final IntentSender target = getIntent().getParcelableExtra(Intent.EXTRA_INTENT); + final IntentSender target = getIntent().getParcelableExtra(Intent.EXTRA_INTENT, android.content.IntentSender.class); try { startIntentSenderForResult(target, -1 /*requestCode*/, null /*fillInIntent*/, 0 /*flagsMask*/, 0 /*flagsValue*/, 0 /*extraFlags*/); diff --git a/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java b/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java index 015238788191..801c934676d7 100644 --- a/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java +++ b/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java @@ -66,7 +66,7 @@ public class HeavyWeightSwitcherActivity extends Activity { requestWindowFeature(Window.FEATURE_NO_TITLE); - mStartIntent = (IntentSender)getIntent().getParcelableExtra(KEY_INTENT); + mStartIntent = (IntentSender)getIntent().getParcelableExtra(KEY_INTENT, android.content.IntentSender.class); mHasResult = getIntent().getBooleanExtra(KEY_HAS_RESULT, false); mCurApp = getIntent().getStringExtra(KEY_CUR_APP); mCurTask = getIntent().getIntExtra(KEY_CUR_TASK, 0); diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java index 070d8ff945ba..47b83be35f87 100644 --- a/core/java/com/android/internal/app/IntentForwarderActivity.java +++ b/core/java/com/android/internal/app/IntentForwarderActivity.java @@ -224,7 +224,7 @@ public class IntentForwarderActivity extends Activity { int selectedProfile = findSelectedProfile(className); sanitizeIntent(intentReceived); intentReceived.putExtra(EXTRA_SELECTED_PROFILE, selectedProfile); - Intent innerIntent = intentReceived.getParcelableExtra(Intent.EXTRA_INTENT); + Intent innerIntent = intentReceived.getParcelableExtra(Intent.EXTRA_INTENT, android.content.Intent.class); if (innerIntent == null) { Slog.wtf(TAG, "Cannot start a chooser intent with no extra " + Intent.EXTRA_INTENT); return; diff --git a/core/java/com/android/internal/app/LaunchAfterAuthenticationActivity.java b/core/java/com/android/internal/app/LaunchAfterAuthenticationActivity.java index 20a025a3ff54..c14d958f91fb 100644 --- a/core/java/com/android/internal/app/LaunchAfterAuthenticationActivity.java +++ b/core/java/com/android/internal/app/LaunchAfterAuthenticationActivity.java @@ -54,7 +54,7 @@ public class LaunchAfterAuthenticationActivity extends Activity { super.onCreate(icicle); final IntentSender onSuccessIntent = getIntent().getParcelableExtra( - EXTRA_ON_SUCCESS_INTENT); + EXTRA_ON_SUCCESS_INTENT, android.content.IntentSender.class); requestDismissKeyguardIfNeeded(onSuccessIntent); } diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index 40429c609150..4b4a91e2f015 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -500,7 +500,7 @@ public class ResolverActivity extends Activity implements // this happens, we check for it here and set the current profile's tab. int selectedProfile = getCurrentProfile(); UserHandle intentUser = getIntent().hasExtra(EXTRA_CALLING_USER) - ? getIntent().getParcelableExtra(EXTRA_CALLING_USER) + ? getIntent().getParcelableExtra(EXTRA_CALLING_USER, android.os.UserHandle.class) : getUser(); if (!getUser().equals(intentUser)) { if (getPersonalProfileUserHandle().equals(intentUser)) { diff --git a/core/java/com/android/internal/app/ResolverListAdapter.java b/core/java/com/android/internal/app/ResolverListAdapter.java index 2ed0f981692e..737d5e348249 100644 --- a/core/java/com/android/internal/app/ResolverListAdapter.java +++ b/core/java/com/android/internal/app/ResolverListAdapter.java @@ -265,6 +265,7 @@ public class ResolverListAdapter extends BaseAdapter { return mResolverListController.getResolversForIntent( /* shouldGetResolvedFilter= */ true, mResolverListCommunicator.shouldGetActivityMetadata(), + mResolverListCommunicator.shouldGetOnlyDefaultActivities(), mIntents); } } @@ -727,6 +728,7 @@ public class ResolverListAdapter extends BaseAdapter { protected List<ResolvedComponentInfo> getResolversForUser(UserHandle userHandle) { return mResolverListController.getResolversForIntentAsUser(true, mResolverListCommunicator.shouldGetActivityMetadata(), + mResolverListCommunicator.shouldGetOnlyDefaultActivities(), mIntents, userHandle); } @@ -820,6 +822,12 @@ public class ResolverListAdapter extends BaseAdapter { boolean shouldGetActivityMetadata(); + /** + * @return true to filter only apps that can handle + * {@link android.content.Intent#CATEGORY_DEFAULT} intents + */ + default boolean shouldGetOnlyDefaultActivities() { return true; }; + Intent getTargetIntent(); void onHandlePackagesChanged(ResolverListAdapter listAdapter); diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java index 27573631b2ce..100fcd817812 100644 --- a/core/java/com/android/internal/app/ResolverListController.java +++ b/core/java/com/android/internal/app/ResolverListController.java @@ -110,17 +110,19 @@ public class ResolverListController { public List<ResolverActivity.ResolvedComponentInfo> getResolversForIntent( boolean shouldGetResolvedFilter, boolean shouldGetActivityMetadata, + boolean shouldGetOnlyDefaultActivities, List<Intent> intents) { return getResolversForIntentAsUser(shouldGetResolvedFilter, shouldGetActivityMetadata, - intents, mUserHandle); + shouldGetOnlyDefaultActivities, intents, mUserHandle); } public List<ResolverActivity.ResolvedComponentInfo> getResolversForIntentAsUser( boolean shouldGetResolvedFilter, boolean shouldGetActivityMetadata, + boolean shouldGetOnlyDefaultActivities, List<Intent> intents, UserHandle userHandle) { - int baseFlags = PackageManager.MATCH_DEFAULT_ONLY + int baseFlags = (shouldGetOnlyDefaultActivities ? PackageManager.MATCH_DEFAULT_ONLY : 0) | PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE | (shouldGetResolvedFilter ? PackageManager.GET_RESOLVED_FILTER : 0) diff --git a/core/java/com/android/internal/app/SuspendedAppActivity.java b/core/java/com/android/internal/app/SuspendedAppActivity.java index ec224e50eb8d..02881372c97f 100644 --- a/core/java/com/android/internal/app/SuspendedAppActivity.java +++ b/core/java/com/android/internal/app/SuspendedAppActivity.java @@ -219,8 +219,8 @@ public class SuspendedAppActivity extends AlertActivity } mSuspendedPackage = intent.getStringExtra(EXTRA_SUSPENDED_PACKAGE); mSuspendingPackage = intent.getStringExtra(EXTRA_SUSPENDING_PACKAGE); - mSuppliedDialogInfo = intent.getParcelableExtra(EXTRA_DIALOG_INFO); - mOnUnsuspend = intent.getParcelableExtra(EXTRA_UNSUSPEND_INTENT); + mSuppliedDialogInfo = intent.getParcelableExtra(EXTRA_DIALOG_INFO, android.content.pm.SuspendDialogInfo.class); + mOnUnsuspend = intent.getParcelableExtra(EXTRA_UNSUSPEND_INTENT, android.content.IntentSender.class); if (mSuppliedDialogInfo != null) { try { mSuspendingAppResources = createContextAsUser( diff --git a/core/java/com/android/internal/app/UnlaunchableAppActivity.java b/core/java/com/android/internal/app/UnlaunchableAppActivity.java index e56d92b48528..077657216119 100644 --- a/core/java/com/android/internal/app/UnlaunchableAppActivity.java +++ b/core/java/com/android/internal/app/UnlaunchableAppActivity.java @@ -62,7 +62,7 @@ public class UnlaunchableAppActivity extends Activity Intent intent = getIntent(); mReason = intent.getIntExtra(EXTRA_UNLAUNCHABLE_REASON, -1); mUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); - mTarget = intent.getParcelableExtra(Intent.EXTRA_INTENT); + mTarget = intent.getParcelableExtra(Intent.EXTRA_INTENT, android.content.IntentSender.class); if (mUserId == UserHandle.USER_NULL) { Log.wtf(TAG, "Invalid user id: " + mUserId + ". Stopping."); diff --git a/core/java/com/android/internal/net/VpnProfile.java b/core/java/com/android/internal/net/VpnProfile.java index b334e9172729..396da5b8869d 100644 --- a/core/java/com/android/internal/net/VpnProfile.java +++ b/core/java/com/android/internal/net/VpnProfile.java @@ -204,7 +204,7 @@ public final class VpnProfile implements Cloneable, Parcelable { excludeLocalRoutes = in.readBoolean(); requiresInternetValidation = in.readBoolean(); final PersistableBundle bundle = - in.readParcelable(PersistableBundle.class.getClassLoader()); + in.readParcelable(PersistableBundle.class.getClassLoader(), android.os.PersistableBundle.class); ikeTunConnParams = (bundle == null) ? null : TunnelConnectionParamsUtils.fromPersistableBundle(bundle); } diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl index e93a7854f1cd..65bec0e405ea 100644 --- a/core/java/com/android/internal/statusbar/IStatusBar.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl @@ -33,6 +33,7 @@ import android.view.InsetsVisibilities; import com.android.internal.statusbar.IAddTileResultCallback; import com.android.internal.statusbar.IUndoMediaTransferCallback; +import com.android.internal.statusbar.LetterboxDetails; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.view.AppearanceRegion; @@ -202,10 +203,12 @@ oneway interface IStatusBar * @param behavior the behavior of the focused window. * @param requestedVisibilities the collection of the requested visibilities of system insets. * @param packageName the package name of the focused app. + * @param letterboxDetails a set of letterbox details of apps visible on the screen. */ void onSystemBarAttributesChanged(int displayId, int appearance, in AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, - int behavior, in InsetsVisibilities requestedVisibilities, String packageName); + int behavior, in InsetsVisibilities requestedVisibilities, String packageName, + in LetterboxDetails[] letterboxDetails); /** * Notifies System UI to show transient bars. The transient bars are system bars, e.g., status diff --git a/core/java/com/android/internal/statusbar/LetterboxDetails.aidl b/core/java/com/android/internal/statusbar/LetterboxDetails.aidl new file mode 100644 index 000000000000..7875796cd3ba --- /dev/null +++ b/core/java/com/android/internal/statusbar/LetterboxDetails.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2022 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.internal.statusbar; + +parcelable LetterboxDetails; diff --git a/core/java/com/android/internal/statusbar/LetterboxDetails.java b/core/java/com/android/internal/statusbar/LetterboxDetails.java new file mode 100644 index 000000000000..5d14ee347482 --- /dev/null +++ b/core/java/com/android/internal/statusbar/LetterboxDetails.java @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2022 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.internal.statusbar; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.graphics.Rect; +import android.os.Parcel; +import android.os.Parcelable; +import android.view.InsetsFlags; +import android.view.ViewDebug; +import android.view.WindowInsetsController.Appearance; + +import com.android.internal.util.DataClass; + +/** + * Details about the letterbox state of an app. + */ +@DataClass( + genParcelable = true, + genAidl = true, + genToString = true, + genGetters = false, + genEqualsHashCode = true +) +public class LetterboxDetails implements Parcelable { + + @NonNull + private final Rect mLetterboxInnerBounds; + @NonNull + private final Rect mLetterboxFullBounds; + private final int mAppAppearance; + + /** + * Returns the bounds of the inner letterbox (app content). + * + * <p>When an app is letterboxed, it is not using the full bounds of its window. Here we return + * the bounds that are being used for the app content. + * + * <pre> + * +-------+---------+-------+ + * | | | | + * | | | | + * | Outer | Inner | Outer | + * | | | | + * | | | | + * +-------+-------- +-------+ + * <pre> + */ + @NonNull + public Rect getLetterboxInnerBounds() { + return mLetterboxInnerBounds; + } + + /** + * Returns the full bounds of the letterbox. + * + * <p>These are the entire bounds of the window where the app is placed. We cannot assume that + * the full bounds are the bounds of the screen, as the app can be in split-screen, or can have + * some margin due to display cutouts. + * + * <pre> + * ---- Full bounds width ---- + * +-------+---------+-------+ | + * | | | | | + * | | | | | + * | Outer | Inner | Outer | + Full bounds height + * | | | | | + * | | | | | + * +-------+-------- +-------+ | + * </pre> + */ + @NonNull + public Rect getLetterboxFullBounds() { + return mLetterboxFullBounds; + } + + /** + * Returns the {@link Appearance} of the inner letterbox (app content). + */ + @Appearance + public int getAppAppearance() { + return mAppAppearance; + } + + /** Returns a string representation of the {@link #getAppAppearance()} property. */ + public String appAppearanceToString() { + return ViewDebug.flagsToString(InsetsFlags.class, "appearance", mAppAppearance); + } + + + + // Code below generated by codegen v1.0.23. + // + // DO NOT MODIFY! + // CHECKSTYLE:OFF Generated code + // + // To regenerate run: + // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/com/android/internal/statusbar/LetterboxDetails.java + // + // To exclude the generated code from IntelliJ auto-formatting enable (one-time): + // Settings > Editor > Code Style > Formatter Control + //@formatter:off + + + @DataClass.Generated.Member + public LetterboxDetails( + @NonNull Rect letterboxInnerBounds, + @NonNull Rect letterboxFullBounds, + int appAppearance) { + this.mLetterboxInnerBounds = letterboxInnerBounds; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mLetterboxInnerBounds); + this.mLetterboxFullBounds = letterboxFullBounds; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mLetterboxFullBounds); + this.mAppAppearance = appAppearance; + + // onConstructed(); // You can define this method to get a callback + } + + @Override + @DataClass.Generated.Member + public String toString() { + // You can override field toString logic by defining methods like: + // String fieldNameToString() { ... } + + return "LetterboxDetails { " + + "letterboxInnerBounds = " + mLetterboxInnerBounds + ", " + + "letterboxFullBounds = " + mLetterboxFullBounds + ", " + + "appAppearance = " + appAppearanceToString() + + " }"; + } + + @Override + @DataClass.Generated.Member + public boolean equals(@Nullable Object o) { + // You can override field equality logic by defining either of the methods like: + // boolean fieldNameEquals(LetterboxDetails other) { ... } + // boolean fieldNameEquals(FieldType otherValue) { ... } + + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + @SuppressWarnings("unchecked") + LetterboxDetails that = (LetterboxDetails) o; + //noinspection PointlessBooleanExpression + return true + && java.util.Objects.equals(mLetterboxInnerBounds, that.mLetterboxInnerBounds) + && java.util.Objects.equals(mLetterboxFullBounds, that.mLetterboxFullBounds) + && mAppAppearance == that.mAppAppearance; + } + + @Override + @DataClass.Generated.Member + public int hashCode() { + // You can override field hashCode logic by defining methods like: + // int fieldNameHashCode() { ... } + + int _hash = 1; + _hash = 31 * _hash + java.util.Objects.hashCode(mLetterboxInnerBounds); + _hash = 31 * _hash + java.util.Objects.hashCode(mLetterboxFullBounds); + _hash = 31 * _hash + mAppAppearance; + return _hash; + } + + @Override + @DataClass.Generated.Member + public void writeToParcel(@NonNull Parcel dest, int flags) { + // You can override field parcelling by defining methods like: + // void parcelFieldName(Parcel dest, int flags) { ... } + + dest.writeTypedObject(mLetterboxInnerBounds, flags); + dest.writeTypedObject(mLetterboxFullBounds, flags); + dest.writeInt(mAppAppearance); + } + + @Override + @DataClass.Generated.Member + public int describeContents() { return 0; } + + /** @hide */ + @SuppressWarnings({"unchecked", "RedundantCast"}) + @DataClass.Generated.Member + protected LetterboxDetails(@NonNull Parcel in) { + // You can override field unparcelling by defining methods like: + // static FieldType unparcelFieldName(Parcel in) { ... } + + Rect letterboxInnerBounds = (Rect) in.readTypedObject(Rect.CREATOR); + Rect letterboxFullBounds = (Rect) in.readTypedObject(Rect.CREATOR); + int appAppearance = in.readInt(); + + this.mLetterboxInnerBounds = letterboxInnerBounds; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mLetterboxInnerBounds); + this.mLetterboxFullBounds = letterboxFullBounds; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mLetterboxFullBounds); + this.mAppAppearance = appAppearance; + + // onConstructed(); // You can define this method to get a callback + } + + @DataClass.Generated.Member + public static final @NonNull Parcelable.Creator<LetterboxDetails> CREATOR + = new Parcelable.Creator<LetterboxDetails>() { + @Override + public LetterboxDetails[] newArray(int size) { + return new LetterboxDetails[size]; + } + + @Override + public LetterboxDetails createFromParcel(@NonNull Parcel in) { + return new LetterboxDetails(in); + } + }; + + @DataClass.Generated( + time = 1656941109526L, + codegenVersion = "1.0.23", + sourceFile = "frameworks/base/core/java/com/android/internal/statusbar/LetterboxDetails.java", + inputSignatures = "private final @android.annotation.NonNull android.graphics.Rect mLetterboxInnerBounds\nprivate final @android.annotation.NonNull android.graphics.Rect mLetterboxFullBounds\nprivate final int mAppAppearance\npublic @android.annotation.NonNull android.graphics.Rect getLetterboxInnerBounds()\npublic @android.annotation.NonNull android.graphics.Rect getLetterboxFullBounds()\npublic @android.view.WindowInsetsController.Appearance int getAppAppearance()\npublic java.lang.String appAppearanceToString()\nclass LetterboxDetails extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genAidl=true, genToString=true, genGetters=false, genEqualsHashCode=true)") + @Deprecated + private void __metadata() {} + + + //@formatter:on + // End of generated code + +} diff --git a/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java index 4dcc82e2e572..8b898f01554f 100644 --- a/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java +++ b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java @@ -43,12 +43,14 @@ public final class RegisterStatusBarResult implements Parcelable { public final InsetsVisibilities mRequestedVisibilities; public final String mPackageName; public final int[] mTransientBarTypes; + public final LetterboxDetails[] mLetterboxDetails; public RegisterStatusBarResult(ArrayMap<String, StatusBarIcon> icons, int disabledFlags1, int appearance, AppearanceRegion[] appearanceRegions, int imeWindowVis, int imeBackDisposition, boolean showImeSwitcher, int disabledFlags2, IBinder imeToken, boolean navbarColorManagedByIme, int behavior, InsetsVisibilities requestedVisibilities, - String packageName, @NonNull int[] transientBarTypes) { + String packageName, @NonNull int[] transientBarTypes, + LetterboxDetails[] letterboxDetails) { mIcons = new ArrayMap<>(icons); mDisabledFlags1 = disabledFlags1; mAppearance = appearance; @@ -63,6 +65,7 @@ public final class RegisterStatusBarResult implements Parcelable { mRequestedVisibilities = requestedVisibilities; mPackageName = packageName; mTransientBarTypes = transientBarTypes; + mLetterboxDetails = letterboxDetails; } @Override @@ -86,6 +89,7 @@ public final class RegisterStatusBarResult implements Parcelable { dest.writeTypedObject(mRequestedVisibilities, 0); dest.writeString(mPackageName); dest.writeIntArray(mTransientBarTypes); + dest.writeParcelableArray(mLetterboxDetails, flags); } /** @@ -112,10 +116,13 @@ public final class RegisterStatusBarResult implements Parcelable { source.readTypedObject(InsetsVisibilities.CREATOR); final String packageName = source.readString(); final int[] transientBarTypes = source.createIntArray(); + final LetterboxDetails[] letterboxDetails = + source.readParcelableArray(null, LetterboxDetails.class); return new RegisterStatusBarResult(icons, disabledFlags1, appearance, appearanceRegions, imeWindowVis, imeBackDisposition, showImeSwitcher, disabledFlags2, imeToken, navbarColorManagedByIme, behavior, - requestedVisibilities, packageName, transientBarTypes); + requestedVisibilities, packageName, transientBarTypes, + letterboxDetails); } @Override diff --git a/core/java/com/android/internal/util/ScreenshotHelper.java b/core/java/com/android/internal/util/ScreenshotHelper.java index f4f438b1f601..518fa530c9a0 100644 --- a/core/java/com/android/internal/util/ScreenshotHelper.java +++ b/core/java/com/android/internal/util/ScreenshotHelper.java @@ -217,8 +217,8 @@ public class ScreenshotHelper { throw new IllegalArgumentException("Bundle does not contain a hardware bitmap"); } - HardwareBuffer buffer = bundle.getParcelable(KEY_BUFFER); - ParcelableColorSpace colorSpace = bundle.getParcelable(KEY_COLOR_SPACE); + HardwareBuffer buffer = bundle.getParcelable(KEY_BUFFER, android.hardware.HardwareBuffer.class); + ParcelableColorSpace colorSpace = bundle.getParcelable(KEY_COLOR_SPACE, android.graphics.ParcelableColorSpace.class); return Bitmap.wrapHardwareBuffer(Objects.requireNonNull(buffer), colorSpace.getColorSpace()); diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl index d550fef968a8..4bed47ceae98 100644 --- a/core/java/com/android/internal/view/IInputMethodManager.aidl +++ b/core/java/com/android/internal/view/IInputMethodManager.aidl @@ -36,10 +36,19 @@ interface IInputMethodManager { int untrustedDisplayId); // TODO: Use ParceledListSlice instead + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = " + + "android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional = true)") List<InputMethodInfo> getInputMethodList(int userId); + + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = " + + "android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional = true)") List<InputMethodInfo> getAwareLockedInputMethodList(int userId, int directBootAwareness); + // TODO: Use ParceledListSlice instead + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = " + + "android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional = true)") List<InputMethodInfo> getEnabledInputMethodList(int userId); + List<InputMethodSubtype> getEnabledInputMethodSubtypeList(in String imiId, boolean allowsImplicitlySelectedSubtypes); InputMethodSubtype getLastInputMethodSubtype(); @@ -48,9 +57,12 @@ interface IInputMethodManager { in ResultReceiver resultReceiver, int reason); boolean hideSoftInput(in IInputMethodClient client, IBinder windowToken, int flags, in ResultReceiver resultReceiver, int reason); + // If windowToken is null, this just does startInput(). Otherwise this reports that a window // has gained focus, and if 'editorInfo' is non-null then also does startInput. // @NonNull + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = " + + "android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional = true)") InputBindResult startInputOrWindowGainedFocus( /* @StartInputReason */ int startInputReason, in IInputMethodClient client, in IBinder windowToken, @@ -62,8 +74,12 @@ interface IInputMethodManager { void showInputMethodPickerFromClient(in IInputMethodClient client, int auxiliarySubtypeMode); + + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = " + + "android.Manifest.permission.WRITE_SECURE_SETTINGS)") void showInputMethodPickerFromSystem(in IInputMethodClient client, int auxiliarySubtypeMode, int displayId); + void showInputMethodAndSubtypeEnablerFromClient(in IInputMethodClient client, String topId); boolean isInputMethodPickerShownForTest(); InputMethodSubtype getCurrentInputMethodSubtype(); @@ -76,8 +92,11 @@ interface IInputMethodManager { int childDisplayId, in float[] matrixValues); oneway void reportPerceptibleAsync(in IBinder windowToken, boolean perceptible); - /** Remove the IME surface. Requires INTERNAL_SYSTEM_WINDOW permission. */ + + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = " + + "android.Manifest.permission.INTERNAL_SYSTEM_WINDOW)") void removeImeSurface(); + /** Remove the IME surface. Requires passing the currently focused window. */ oneway void removeImeSurfaceFromWindowAsync(in IBinder windowToken); void startProtoDump(in byte[] protoDump, int source, String where); @@ -90,6 +109,9 @@ interface IInputMethodManager { /** Start Stylus handwriting session **/ void startStylusHandwriting(in IInputMethodClient client); + /** Returns {@code true} if currently selected IME supports Stylus handwriting. */ + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = " + + "android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional = true)") boolean isStylusHandwritingAvailableAsUser(int userId); } diff --git a/core/java/com/android/internal/widget/CallLayout.java b/core/java/com/android/internal/widget/CallLayout.java index 83345dad8ed9..acb0e44f29a6 100644 --- a/core/java/com/android/internal/widget/CallLayout.java +++ b/core/java/com/android/internal/widget/CallLayout.java @@ -125,7 +125,7 @@ public class CallLayout extends FrameLayout { */ @RemotableViewMethod public void setData(Bundle extras) { - setUser(extras.getParcelable(Notification.EXTRA_CALL_PERSON)); + setUser(extras.getParcelable(Notification.EXTRA_CALL_PERSON, android.app.Person.class)); updateCallLayout(); } diff --git a/core/java/com/android/internal/widget/ConversationLayout.java b/core/java/com/android/internal/widget/ConversationLayout.java index 4706affa3541..9f21760a49e0 100644 --- a/core/java/com/android/internal/widget/ConversationLayout.java +++ b/core/java/com/android/internal/widget/ConversationLayout.java @@ -390,11 +390,11 @@ public class ConversationLayout extends FrameLayout = Notification.MessagingStyle.Message.getMessagesFromBundleArray(histMessages); // mUser now set (would be nice to avoid the side effect but WHATEVER) - setUser(extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON)); + setUser(extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON, android.app.Person.class)); // Append remote input history to newMessages (again, side effect is lame but WHATEVS) RemoteInputHistoryItem[] history = (RemoteInputHistoryItem[]) - extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS); + extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS, android.app.RemoteInputHistoryItem.class); addRemoteInputHistoryToMessages(newMessages, history); boolean showSpinner = diff --git a/core/java/com/android/internal/widget/MessagingLayout.java b/core/java/com/android/internal/widget/MessagingLayout.java index 9ac6ef77bc07..67b671e01413 100644 --- a/core/java/com/android/internal/widget/MessagingLayout.java +++ b/core/java/com/android/internal/widget/MessagingLayout.java @@ -164,9 +164,9 @@ public class MessagingLayout extends FrameLayout Parcelable[] histMessages = extras.getParcelableArray(Notification.EXTRA_HISTORIC_MESSAGES); List<Notification.MessagingStyle.Message> newHistoricMessages = Notification.MessagingStyle.Message.getMessagesFromBundleArray(histMessages); - setUser(extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON)); + setUser(extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON, android.app.Person.class)); RemoteInputHistoryItem[] history = (RemoteInputHistoryItem[]) - extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS); + extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS, android.app.RemoteInputHistoryItem.class); addRemoteInputHistoryToMessages(newMessages, history); boolean showSpinner = extras.getBoolean(Notification.EXTRA_SHOW_REMOTE_INPUT_SPINNER, false); diff --git a/core/res/res/values-mcc440-mnc20/config.xml b/core/res/res/values-mcc440-mnc20/config.xml index 62001d904482..7a483421a975 100644 --- a/core/res/res/values-mcc440-mnc20/config.xml +++ b/core/res/res/values-mcc440-mnc20/config.xml @@ -23,6 +23,6 @@ <!-- Configure mobile network MTU. Carrier specific value is set here. --> - <integer name="config_mobile_mtu">1422</integer> + <integer name="config_mobile_mtu">1358</integer> </resources> diff --git a/core/tests/coretests/src/android/view/WindowInfoTest.java b/core/tests/coretests/src/android/view/WindowInfoTest.java index afc2c002db08..f9e3f43b562c 100644 --- a/core/tests/coretests/src/android/view/WindowInfoTest.java +++ b/core/tests/coretests/src/android/view/WindowInfoTest.java @@ -30,6 +30,7 @@ import android.graphics.Matrix; import android.os.IBinder; import android.os.Parcel; import android.platform.test.annotations.Presubmit; +import android.text.TextUtils; import android.view.accessibility.AccessibilityNodeInfo; import androidx.test.filters.SmallTest; @@ -82,22 +83,7 @@ public class WindowInfoTest { public void testDefaultValues() { WindowInfo w = WindowInfo.obtain(); - assertEquals(0, w.type); - assertEquals(0, w.layer); - assertEquals(AccessibilityNodeInfo.UNDEFINED_NODE_ID, w.accessibilityIdOfAnchor); - assertEquals(Display.INVALID_DISPLAY, w.displayId); - assertEquals(ActivityTaskManager.INVALID_TASK_ID, w.taskId); - assertNull(w.title); - assertNull(w.token); - assertNull(w.childTokens); - assertNull(w.parentToken); - assertNull(w.activityToken); - assertFalse(w.focused); - assertFalse(w.inPictureInPicture); - assertFalse(w.hasFlagWatchOutsideTouch); - assertTrue(w.regionInScreen.isEmpty()); - assertEquals(w.mTransformMatrix.length, 9); - assertTrue(w.mMagnificationSpec.isNop()); + assertDefaultValue(w); } @SmallTest @@ -114,6 +100,37 @@ public class WindowInfoTest { } } + @SmallTest + @Test + public void testRecycle_fallbackToDefaultValues() { + WindowInfo w = WindowInfo.obtain(); + initTestWindowInfo(w); + w.recycle(); + + assertDefaultValue(w); + } + + private static void assertDefaultValue(WindowInfo windowinfo) { + assertEquals(0, windowinfo.type); + assertEquals(0, windowinfo.layer); + assertEquals(AccessibilityNodeInfo.UNDEFINED_NODE_ID, windowinfo.accessibilityIdOfAnchor); + assertEquals(Display.INVALID_DISPLAY, windowinfo.displayId); + assertEquals(ActivityTaskManager.INVALID_TASK_ID, windowinfo.taskId); + assertNull(windowinfo.title); + assertNull(windowinfo.token); + if (windowinfo.childTokens != null) { + assertTrue(windowinfo.childTokens.isEmpty()); + } + assertNull(windowinfo.parentToken); + assertNull(windowinfo.activityToken); + assertFalse(windowinfo.focused); + assertFalse(windowinfo.inPictureInPicture); + assertFalse(windowinfo.hasFlagWatchOutsideTouch); + assertTrue(windowinfo.regionInScreen.isEmpty()); + assertEquals(windowinfo.mTransformMatrix.length, 9); + assertTrue(windowinfo.mMagnificationSpec.isNop()); + } + private boolean areWindowsEqual(WindowInfo w1, WindowInfo w2) { boolean equality = w1.toString().contentEquals(w2.toString()); equality &= w1.token == w2.token; @@ -123,6 +140,7 @@ public class WindowInfoTest { equality &= w1.regionInScreen.equals(w2.regionInScreen); equality &= w1.mMagnificationSpec.equals(w2.mMagnificationSpec); equality &= Arrays.equals(w1.mTransformMatrix, w2.mTransformMatrix); + equality &= TextUtils.equals(w1.title, w2.title); return equality; } diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java index 82148422aabf..e8c7ce0b312b 100644 --- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java +++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java @@ -266,6 +266,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); final IChooserWrapper activity = (IChooserWrapper) mActivityRule.launchActivity( @@ -289,6 +290,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); mActivityRule.launchActivity(Intent.createChooser(sendIntent, "chooser test")); @@ -309,6 +311,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); @@ -329,6 +332,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); @@ -352,6 +356,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); @@ -378,6 +383,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); @@ -403,6 +409,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); @@ -424,6 +431,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); @@ -478,6 +486,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); @@ -518,6 +527,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); @@ -552,6 +562,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(null); Intent sendIntent = createSendTextIntent(); @@ -587,6 +598,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); @@ -649,6 +661,7 @@ public class ChooserActivityTest { when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); when(ChooserActivityOverrideData.getInstance().resolverListController.getLastChosen()) .thenReturn(resolvedComponentInfos.get(0).getResolveInfoAt(0)); @@ -688,6 +701,7 @@ public class ChooserActivityTest { when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); final IChooserWrapper activity = (IChooserWrapper) @@ -720,6 +734,7 @@ public class ChooserActivityTest { when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); final ChooserActivity activity = @@ -747,6 +762,7 @@ public class ChooserActivityTest { when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); MetricsLogger mockLogger = ChooserActivityOverrideData.getInstance().metricsLogger; @@ -776,6 +792,7 @@ public class ChooserActivityTest { when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); final IChooserWrapper activity = (IChooserWrapper) @@ -846,6 +863,7 @@ public class ChooserActivityTest { when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); final IChooserWrapper activity = (IChooserWrapper) @@ -922,6 +940,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); @@ -958,6 +977,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); @@ -997,6 +1017,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); @@ -1091,6 +1112,7 @@ public class ChooserActivityTest { when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); @@ -1124,6 +1146,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); @@ -1157,6 +1180,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); @@ -1189,6 +1213,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); @@ -1218,6 +1243,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); @@ -1250,6 +1276,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); @@ -1284,6 +1311,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); when( @@ -1323,6 +1351,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); @@ -1365,6 +1394,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); @@ -1409,6 +1439,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); @@ -1485,6 +1516,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); @@ -1566,6 +1598,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); // Create direct share target @@ -1638,6 +1671,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); // Create direct share target @@ -1745,6 +1779,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); @@ -2060,6 +2095,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); @@ -2142,6 +2178,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); @@ -2229,6 +2266,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); @@ -2298,6 +2336,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); @@ -2446,6 +2485,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); Intent sendIntent = createSendTextIntent(); @@ -2475,6 +2515,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); Intent sendIntent = createSendTextIntent(); @@ -2528,6 +2569,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); Intent chooserIntent = createChooserIntent(createSendTextIntent(), @@ -2664,6 +2706,7 @@ public class ChooserActivityTest { when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); // Create caller target which is duplicate with one of app targets @@ -3057,6 +3100,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); when( @@ -3066,6 +3110,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(new ArrayList<>(workResolvedComponentInfos)); when( @@ -3075,6 +3120,7 @@ public class ChooserActivityTest { .getResolversForIntentAsUser( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class), eq(UserHandle.SYSTEM))) .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); @@ -3131,6 +3177,7 @@ public class ChooserActivityTest { .getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(resolvedComponentInfos); } diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java index 43fba529182e..92c05b0fe9fc 100644 --- a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java +++ b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java @@ -96,6 +96,7 @@ public class ResolverActivityTest { when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); @@ -127,6 +128,7 @@ public class ResolverActivityTest { when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); waitForIdle(); @@ -171,6 +173,7 @@ public class ResolverActivityTest { when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); waitForIdle(); @@ -203,6 +206,7 @@ public class ResolverActivityTest { when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); when(sOverrides.resolverListController.getLastChosen()) .thenReturn(resolvedComponentInfos.get(0).getResolveInfoAt(0)); @@ -273,6 +277,7 @@ public class ResolverActivityTest { when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); @@ -317,6 +322,7 @@ public class ResolverActivityTest { when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); when(sOverrides.resolverListController.getLastChosen()) .thenReturn(resolvedComponentInfos.get(1).getResolveInfoAt(0)); @@ -807,6 +813,7 @@ public class ResolverActivityTest { createResolvedComponentsForTestWithOtherProfile(2, /* userId */ 10); when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); Intent sendIntent = createSendImageIntent(); @@ -831,6 +838,7 @@ public class ResolverActivityTest { createResolvedComponentsForTest(1); when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); Intent sendIntent = createSendImageIntent(); @@ -888,6 +896,7 @@ public class ResolverActivityTest { when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); when(sOverrides.resolverListController.getLastChosen()) .thenReturn(resolvedComponentInfos.get(1).getResolveInfoAt(0)); @@ -965,13 +974,16 @@ public class ResolverActivityTest { List<ResolvedComponentInfo> workResolvedComponentInfos) { when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos); when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(), Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.isA(List.class), eq(UserHandle.SYSTEM))) .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverListControllerTest.java b/core/tests/coretests/src/com/android/internal/app/ResolverListControllerTest.java index e16d44854516..42593f60094b 100644 --- a/core/tests/coretests/src/com/android/internal/app/ResolverListControllerTest.java +++ b/core/tests/coretests/src/com/android/internal/app/ResolverListControllerTest.java @@ -20,11 +20,14 @@ import static junit.framework.Assert.assertEquals; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasSize; +import static org.mockito.ArgumentMatchers.intThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyLong; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.usage.IUsageStatsManager; @@ -48,6 +51,7 @@ import com.android.internal.app.ResolverActivity.ResolvedComponentInfo; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentMatcher; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; @@ -78,6 +82,8 @@ public class ResolverListControllerTest { Configuration config = new Configuration(); config.locale = Locale.getDefault(); List<ResolveInfo> services = new ArrayList<>(); + mUsm = new UsageStatsManager(mMockContext, mMockService); + when(mMockContext.getSystemService(Context.USAGE_STATS_SERVICE)).thenReturn(mUsm); when(mMockPackageManager.queryIntentServices(any(), anyInt())).thenReturn(services); when(mMockResources.getConfiguration()).thenReturn(config); when(mMockContext.getResources()).thenReturn(mMockResources); @@ -112,8 +118,6 @@ public class ResolverListControllerTest { doAnswer(answer).when(mMockService).reportChooserSelection( anyString(), anyInt(), anyString(), any(), anyString()); when(mMockContext.getOpPackageName()).thenReturn(refererPackage); - mUsm = new UsageStatsManager(mMockContext, mMockService); - when(mMockContext.getSystemService(Context.USAGE_STATS_SERVICE)).thenReturn(mUsm); mController = new ResolverListController(mMockContext, mMockPackageManager, sendIntent, refererPackage, UserHandle.USER_CURRENT, /* userHandle */ UserHandle.SYSTEM); mController.sort(new ArrayList<ResolvedComponentInfo>()); @@ -129,8 +133,6 @@ public class ResolverListControllerTest { Intent sendIntent = createSendImageIntent(annotation); String refererPackage = "test_referer_package"; List<ResolvedComponentInfo> resolvedComponents = createResolvedComponentsForTest(10); - mUsm = new UsageStatsManager(mMockContext, mMockService); - when(mMockContext.getSystemService(Context.USAGE_STATS_SERVICE)).thenReturn(mUsm); mController = new ResolverListController(mMockContext, mMockPackageManager, sendIntent, refererPackage, UserHandle.USER_CURRENT, /* userHandle */ UserHandle.SYSTEM); List<ResolvedComponentInfo> topKList = new ArrayList<>(resolvedComponents); @@ -151,6 +153,102 @@ public class ResolverListControllerTest { sortList, topKList); } + @Test + public void getResolversForIntent_usesResultsFromPackageManager() { + mockStats(); + List<ResolveInfo> infos = new ArrayList<>(); + infos.add(ResolverDataProvider.createResolveInfo(0, UserHandle.USER_CURRENT)); + when(mMockPackageManager.queryIntentActivitiesAsUser(any(), anyInt(), + any(UserHandle.class))).thenReturn(infos); + mController = new ResolverListController(mMockContext, mMockPackageManager, + createSendImageIntent("test"), null, UserHandle.USER_CURRENT, + /* userHandle= */ UserHandle.SYSTEM); + List<Intent> intents = new ArrayList<>(); + intents.add(createActionMainIntent()); + + List<ResolvedComponentInfo> resolvers = mController + .getResolversForIntent( + /* shouldGetResolvedFilter= */ true, + /* shouldGetActivityMetadata= */ true, + /* shouldGetOnlyDefaultActivities= */ true, + intents); + + assertThat(resolvers, hasSize(1)); + assertThat(resolvers.get(0).getResolveInfoAt(0), is(infos.get(0))); + } + + @Test + public void getResolversForIntent_shouldGetOnlyDefaultActivitiesTrue_addsFlag() { + mockStats(); + List<ResolveInfo> infos = new ArrayList<>(); + infos.add(ResolverDataProvider.createResolveInfo(0, UserHandle.USER_CURRENT)); + when(mMockPackageManager.queryIntentActivitiesAsUser(any(), anyInt(), + any(UserHandle.class))).thenReturn(infos); + mController = new ResolverListController(mMockContext, mMockPackageManager, + createSendImageIntent("test"), null, UserHandle.USER_CURRENT, + /* userHandle= */ UserHandle.SYSTEM); + List<Intent> intents = new ArrayList<>(); + intents.add(createActionMainIntent()); + + mController + .getResolversForIntent( + /* shouldGetResolvedFilter= */ true, + /* shouldGetActivityMetadata= */ true, + /* shouldGetOnlyDefaultActivities= */ true, + intents); + + verify(mMockPackageManager).queryIntentActivitiesAsUser(any(), + containsFlag(PackageManager.MATCH_DEFAULT_ONLY), any()); + } + + @Test + public void getResolversForIntent_shouldGetOnlyDefaultActivitiesFalse_doesNotAddFlag() { + mockStats(); + List<ResolveInfo> infos = new ArrayList<>(); + infos.add(ResolverDataProvider.createResolveInfo(0, UserHandle.USER_CURRENT)); + when(mMockPackageManager.queryIntentActivitiesAsUser(any(), anyInt(), + any(UserHandle.class))).thenReturn(infos); + mController = new ResolverListController(mMockContext, mMockPackageManager, + createSendImageIntent("test"), null, UserHandle.USER_CURRENT, + /* userHandle= */ UserHandle.SYSTEM); + List<Intent> intents = new ArrayList<>(); + intents.add(createActionMainIntent()); + + mController + .getResolversForIntent( + /* shouldGetResolvedFilter= */ true, + /* shouldGetActivityMetadata= */ true, + /* shouldGetOnlyDefaultActivities= */ false, + intents); + + verify(mMockPackageManager).queryIntentActivitiesAsUser(any(), + doesNotContainFlag(PackageManager.MATCH_DEFAULT_ONLY), any()); + } + + private int containsFlag(int flag) { + return intThat(new FlagMatcher(flag, /* contains= */ true)); + } + + private int doesNotContainFlag(int flag) { + return intThat(new FlagMatcher(flag, /* contains= */ false)); + } + + public static class FlagMatcher implements ArgumentMatcher<Integer> { + + private final int mFlag; + private final boolean mContains; + + public FlagMatcher(int flag, boolean contains) { + mFlag = flag; + mContains = contains; + } + + @Override + public boolean matches(Integer integer) { + return ((integer & mFlag) != 0) == mContains; + } + } + private UsageStats initStats(String packageName, String action, String annotation, int count) { ArrayMap<String, ArrayMap<String, Integer>> chooserCounts = new ArrayMap<>(); @@ -174,6 +272,24 @@ public class ResolverListControllerTest { return sendIntent; } + private Intent createActionMainIntent() { + Intent sendIntent = new Intent(); + sendIntent.setAction(Intent.ACTION_MAIN); + sendIntent.addCategory(Intent.CATEGORY_LAUNCHER); + return sendIntent; + } + + private void mockStats() { + final List<UsageStats> slices = new ArrayList<>(); + ParceledListSlice<UsageStats> stats = new ParceledListSlice<>(slices); + try { + when(mMockService.queryUsageStats(anyInt(), anyLong(), anyLong(), anyString(), + anyInt())).thenReturn(stats); + } catch (RemoteException e) { + e.printStackTrace(); + } + } + private Integer getCount( UsageStatsManager usm, String packageName, String action, String annotation) { if (usm == null) { diff --git a/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java b/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java index 0f05be06bff6..c53fb23ba948 100644 --- a/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java +++ b/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java @@ -20,6 +20,7 @@ import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_B import static com.google.common.truth.Truth.assertThat; +import android.graphics.Rect; import android.os.Binder; import android.os.Parcel; import android.os.UserHandle; @@ -48,7 +49,11 @@ public class RegisterStatusBarResultTest { final ArrayMap<String, StatusBarIcon> iconMap = new ArrayMap<>(); iconMap.put(dumyIconKey, new StatusBarIcon("com.android.internal.statusbar.test", UserHandle.of(100), 123, 1, 2, "dummyIconDescription")); - + final LetterboxDetails letterboxDetails = new LetterboxDetails( + /* letterboxInnerBounds= */ new Rect(1, 2, 3, 4), + /* letterboxFullBounds= */ new Rect(5, 6, 7, 8), + /* appAppearance= */ 321 + ); final RegisterStatusBarResult original = new RegisterStatusBarResult(iconMap, 0x2 /* disabledFlags1 */, 0x4 /* appearance */, @@ -62,7 +67,8 @@ public class RegisterStatusBarResultTest { BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE, new InsetsVisibilities() /* requestedVisibilities */, "test" /* packageName */, - new int[0] /* transientBarTypes */); + new int[0] /* transientBarTypes */, + new LetterboxDetails[] {letterboxDetails}); final RegisterStatusBarResult copy = clone(original); @@ -84,6 +90,7 @@ public class RegisterStatusBarResultTest { assertThat(copy.mRequestedVisibilities).isEqualTo(original.mRequestedVisibilities); assertThat(copy.mPackageName).isEqualTo(original.mPackageName); assertThat(copy.mTransientBarTypes).isEqualTo(original.mTransientBarTypes); + assertThat(copy.mLetterboxDetails).isEqualTo(original.mLetterboxDetails); } private RegisterStatusBarResult clone(RegisterStatusBarResult original) { diff --git a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java index 8d3751e6ad6c..47f70ddf2d42 100644 --- a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java +++ b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java @@ -207,8 +207,8 @@ public class ActivityThreadClientTest { final Configuration currentConfig = new Configuration(); assertFalse("Must not report change if no public diff", - shouldReportChange(0 /* publicDiff */, currentConfig, newConfig, - null /* sizeBuckets */, 0 /* handledConfigChanges */)); + shouldReportChange(currentConfig, newConfig, null /* sizeBuckets */, + 0 /* handledConfigChanges */)); final int[] verticalThresholds = {100, 400}; final SizeConfigurationBuckets buckets = new SizeConfigurationBuckets( @@ -221,25 +221,25 @@ public class ActivityThreadClientTest { newConfig.screenHeightDp = 300; assertFalse("Must not report changes if the diff is small and not handled", - shouldReportChange(CONFIG_SCREEN_SIZE /* publicDiff */, currentConfig, - newConfig, buckets, CONFIG_FONT_SCALE /* handledConfigChanges */)); + shouldReportChange(currentConfig, newConfig, buckets, + CONFIG_FONT_SCALE /* handledConfigChanges */)); assertTrue("Must report changes if the small diff is handled", - shouldReportChange(CONFIG_SCREEN_SIZE /* publicDiff */, currentConfig, newConfig, - buckets, CONFIG_SCREEN_SIZE /* handledConfigChanges */)); + shouldReportChange(currentConfig, newConfig, buckets, + CONFIG_SCREEN_SIZE /* handledConfigChanges */)); currentConfig.fontScale = 0.8f; newConfig.fontScale = 1.2f; assertTrue("Must report handled changes regardless of small unhandled change", - shouldReportChange(CONFIG_SCREEN_SIZE | CONFIG_FONT_SCALE /* publicDiff */, - currentConfig, newConfig, buckets, CONFIG_FONT_SCALE /* handledConfigChanges */)); + shouldReportChange(currentConfig, newConfig, buckets, + CONFIG_FONT_SCALE /* handledConfigChanges */)); newConfig.screenHeightDp = 500; assertFalse("Must not report changes if there's unhandled big changes", - shouldReportChange(CONFIG_SCREEN_SIZE | CONFIG_FONT_SCALE /* publicDiff */, - currentConfig, newConfig, buckets, CONFIG_FONT_SCALE /* handledConfigChanges */)); + shouldReportChange(currentConfig, newConfig, buckets, + CONFIG_FONT_SCALE /* handledConfigChanges */)); } private void recreateAndVerifyNoRelaunch(ActivityThread activityThread, TestActivity activity) { diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt index c18c8ce345fc..19c573b0c15d 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt @@ -77,11 +77,6 @@ open class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec } } - /** {@inheritDoc} */ - @FlakyTest(bugId = 206753786) - @Test - override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales() - /** * Checks [pipApp] window remains visible throughout the animation */ diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt index 0333577b0d2a..c2ed5a1494c9 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt @@ -28,7 +28,6 @@ import com.android.server.wm.flicker.dsl.FlickerBuilder import com.android.server.wm.flicker.entireScreenCovered import com.android.server.wm.flicker.helpers.WindowUtils import com.android.server.wm.flicker.navBarLayerRotatesAndScales -import com.android.server.wm.flicker.statusBarLayerRotatesScales import com.android.server.wm.traces.common.FlickerComponentName import com.android.wm.shell.flicker.helpers.FixedAppHelper import com.android.wm.shell.flicker.pip.PipTransition.BroadcastActionTrigger.Companion.ORIENTATION_LANDSCAPE @@ -116,14 +115,6 @@ class EnterPipToOtherOrientationTest( override fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales() /** - * Checks that the [FlickerComponentName.STATUS_BAR] has the correct position at - * the start and end of the transition - */ - @FlakyTest(bugId = 206753786) - @Test - override fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales() - - /** * Checks that all parts of the screen are covered at the start and end of the transition * * TODO b/197726599 Prevents all states from being checked diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt index 32022ad5f018..4e7a9ff10df1 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt @@ -81,11 +81,6 @@ class ExitPipViaExpandButtonClickTest( } /** {@inheritDoc} */ - @FlakyTest(bugId = 206753786) - @Test - override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales() - - /** {@inheritDoc} */ @FlakyTest(bugId = 197726610) @Test override fun pipLayerExpands() = super.pipLayerExpands() diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt index f28c1e93dfb9..77dcbe0b489b 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt @@ -18,7 +18,6 @@ package com.android.wm.shell.flicker.pip import android.platform.test.annotations.Presubmit import android.view.Surface -import android.platform.test.annotations.FlakyTest import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter @@ -64,11 +63,6 @@ class ExitPipWithDismissButtonTest(testSpec: FlickerTestParameter) : ExitPipTran } } - /** {@inheritDoc} */ - @FlakyTest(bugId = 206753786) - @Test - override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales() - /** * Checks that the focus changes between the pip menu window and the launcher when clicking the * dismiss button on pip menu to close the pip window. diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt index 210b1968b2da..b9e72a460a5f 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt @@ -25,7 +25,6 @@ import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.FlickerTestParameterFactory import com.android.server.wm.flicker.annotation.Group3 import com.android.server.wm.flicker.dsl.FlickerBuilder -import com.android.server.wm.flicker.statusBarLayerRotatesScales import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -81,10 +80,6 @@ class ExitPipWithSwipeDownTest(testSpec: FlickerTestParameter) : ExitPipTransiti @Test override fun pipLayerBecomesInvisible() = super.pipLayerBecomesInvisible() - @FlakyTest(bugId = 206753786) - @Test - override fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales() - /** * Checks that the focus doesn't change between windows during the transition */ diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt index dc1fdde18d1b..32900b17e60a 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt @@ -168,10 +168,6 @@ class ExpandPipOnDoubleClickTest(testSpec: FlickerTestParameter) : PipTransition } } - @FlakyTest(bugId = 206753786) - @Test - override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales() - companion object { /** * Creates the test configurations. diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt index 4935fb003dae..768c0905b473 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt @@ -17,7 +17,6 @@ package com.android.wm.shell.flicker.pip import android.view.Surface -import android.platform.test.annotations.FlakyTest import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter @@ -26,7 +25,6 @@ import com.android.server.wm.flicker.annotation.Group3 import com.android.server.wm.flicker.dsl.FlickerBuilder import com.android.server.wm.flicker.traces.region.RegionSubject import org.junit.FixMethodOrder -import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters import org.junit.runners.Parameterized @@ -80,11 +78,6 @@ open class MovePipDownShelfHeightChangeTest( current.isHigherOrEqual(previous.region) } - /** {@inheritDoc} */ - @FlakyTest(bugId = 206753786) - @Test - override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales() - companion object { /** * Creates the test configurations. diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt index 42af1bbf58ab..2c158b8c9969 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt @@ -29,7 +29,6 @@ import com.android.server.wm.flicker.entireScreenCovered import com.android.server.wm.flicker.helpers.WindowUtils import com.android.server.wm.flicker.helpers.setRotation import com.android.server.wm.flicker.navBarLayerRotatesAndScales -import com.android.server.wm.flicker.statusBarLayerRotatesScales import com.android.wm.shell.flicker.helpers.FixedAppHelper import org.junit.FixMethodOrder import org.junit.Test @@ -96,13 +95,6 @@ open class PipRotationTest(testSpec: FlickerTestParameter) : PipTransition(testS override fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales() /** - * Checks the position of the status bar at the start and end of the transition - */ - @FlakyTest(bugId = 206753786) - @Test - override fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales() - - /** * Checks that [fixedApp] layer is within [screenBoundsStart] at the start of the transition */ @Presubmit diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt index 83d3fe260928..1f078b425db2 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt @@ -116,10 +116,6 @@ open class SetRequestedOrientationWhilePinnedTest( @Test override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales() - @FlakyTest(bugId = 206753786) - @Test - override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales() - @Presubmit @Test fun pipWindowInsideDisplay() { diff --git a/location/java/android/location/SettingInjectorService.java b/location/java/android/location/SettingInjectorService.java index d6f8a7ca3cfc..2aa812b6756e 100644 --- a/location/java/android/location/SettingInjectorService.java +++ b/location/java/android/location/SettingInjectorService.java @@ -179,7 +179,7 @@ public abstract class SettingInjectorService extends Service { * intent. */ private void sendStatus(Intent intent, String summary, boolean enabled) { - Messenger messenger = intent.getParcelableExtra(MESSENGER_KEY); + Messenger messenger = intent.getParcelableExtra(MESSENGER_KEY, android.os.Messenger.class); // Bail out to avoid crashing GmsCore with incoming malicious Intent. if (messenger == null) { return; diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java index c2be2efe19c6..d7f3338f1f98 100644 --- a/media/java/android/media/MediaCodec.java +++ b/media/java/android/media/MediaCodec.java @@ -2320,6 +2320,10 @@ final public class MediaCodec { */ public final void start() { native_start(); + synchronized(mBufferLock) { + cacheBuffers(true /* input */); + cacheBuffers(false /* input */); + } } private native final void native_start(); @@ -3951,9 +3955,6 @@ final public class MediaCodec { + "objects and attach to QueueRequest objects."); } if (mCachedInputBuffers == null) { - cacheBuffers(true /* input */); - } - if (mCachedInputBuffers == null) { throw new IllegalStateException(); } // FIXME: check codec status @@ -3992,9 +3993,6 @@ final public class MediaCodec { + "Please use getOutputFrame to get output frames."); } if (mCachedOutputBuffers == null) { - cacheBuffers(false /* input */); - } - if (mCachedOutputBuffers == null) { throw new IllegalStateException(); } // FIXME: check codec status diff --git a/media/java/android/media/MediaMetadata.java b/media/java/android/media/MediaMetadata.java index db5e52a44c8a..7b3a56801a35 100644 --- a/media/java/android/media/MediaMetadata.java +++ b/media/java/android/media/MediaMetadata.java @@ -500,7 +500,7 @@ public final class MediaMetadata implements Parcelable { public Rating getRating(@RatingKey String key) { Rating rating = null; try { - rating = mBundle.getParcelable(key); + rating = mBundle.getParcelable(key, android.media.Rating.class); } catch (Exception e) { // ignore, value was not a bitmap Log.w(TAG, "Failed to retrieve a key as Rating.", e); @@ -518,7 +518,7 @@ public final class MediaMetadata implements Parcelable { public Bitmap getBitmap(@BitmapKey String key) { Bitmap bmp = null; try { - bmp = mBundle.getParcelable(key); + bmp = mBundle.getParcelable(key, android.graphics.Bitmap.class); } catch (Exception e) { // ignore, value was not a bitmap Log.w(TAG, "Failed to retrieve a key as Bitmap.", e); diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java index 7d57734defc5..d7fc205d28d3 100644 --- a/media/java/android/media/MediaRouter.java +++ b/media/java/android/media/MediaRouter.java @@ -3184,7 +3184,7 @@ public class MediaRouter { public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED)) { updateWifiDisplayStatus((WifiDisplayStatus) intent.getParcelableExtra( - DisplayManager.EXTRA_WIFI_DISPLAY_STATUS)); + DisplayManager.EXTRA_WIFI_DISPLAY_STATUS, android.hardware.display.WifiDisplayStatus.class)); } } } diff --git a/media/java/android/media/RemoteController.java b/media/java/android/media/RemoteController.java index 00fc2757a702..a6e8fa0644df 100644 --- a/media/java/android/media/RemoteController.java +++ b/media/java/android/media/RemoteController.java @@ -407,7 +407,7 @@ import java.util.List; mEditableKeys = editableKeys; mEditorArtwork = (Bitmap) metadata.getParcelable( - String.valueOf(MediaMetadataEditor.BITMAP_KEY_ARTWORK)); + String.valueOf(MediaMetadataEditor.BITMAP_KEY_ARTWORK), android.graphics.Bitmap.class); if (mEditorArtwork != null) { cleanupBitmapFromBundle(MediaMetadataEditor.BITMAP_KEY_ARTWORK); } diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java index bc00c404b11e..9e265d8339dd 100644 --- a/media/java/android/media/session/MediaSession.java +++ b/media/java/android/media/session/MediaSession.java @@ -917,7 +917,7 @@ public final class MediaSession { public boolean onMediaButtonEvent(@NonNull Intent mediaButtonIntent) { if (mSession != null && mHandler != null && Intent.ACTION_MEDIA_BUTTON.equals(mediaButtonIntent.getAction())) { - KeyEvent ke = mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); + KeyEvent ke = mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT, android.view.KeyEvent.class); if (ke != null && ke.getAction() == KeyEvent.ACTION_DOWN) { PlaybackState state = mSession.mPlaybackState; long validActions = state == null ? 0 : state.getActions(); diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index 861d84d752be..8e702dbabdbe 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -576,7 +576,7 @@ <string name="user_setup_dialog_message" msgid="269931619868102841">"مطمئن شوید شخص در دسترس است تا دستگاه را بگیرد و فضایش را تنظیم کند"</string> <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"اکنون نمایه را تنظیم میکنید؟"</string> <string name="user_setup_button_setup_now" msgid="1708269547187760639">"اکنون تنظیم شود"</string> - <string name="user_setup_button_setup_later" msgid="8712980133555493516">"اکنون نه"</string> + <string name="user_setup_button_setup_later" msgid="8712980133555493516">"حالا نه"</string> <string name="user_add_user_type_title" msgid="551279664052914497">"افزودن"</string> <string name="user_new_user_name" msgid="60979820612818840">"کاربر جدید"</string> <string name="user_new_profile_name" msgid="2405500423304678841">"نمایه جدید"</string> diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml index 78c7ab48d778..75abf997a8cf 100644 --- a/packages/SettingsLib/res/values-mn/strings.xml +++ b/packages/SettingsLib/res/values-mn/strings.xml @@ -100,13 +100,13 @@ <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Холбогдсон (медиа байхгүй)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"Холбогдсон (мессежийн хандалт байхгүй)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"Холбогдсон (утас эсвэл медиа байхгүй)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string> - <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Холбогдсон, батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> - <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Холбогдсон (утас байхгүй), батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> - <string name="bluetooth_connected_no_a2dp_battery_level" msgid="6499078454894324287">"Холбогдсон (медиа байхгүй), батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> - <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"Холбогдсон (утас эсвэл медиа байхгүй), батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> - <string name="bluetooth_active_battery_level" msgid="3450745316700494425">"Идэвхтэй, батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"Холбогдсон, батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> + <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Холбогдсон (утас байхгүй), батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> + <string name="bluetooth_connected_no_a2dp_battery_level" msgid="6499078454894324287">"Холбогдсон (медиа байхгүй), батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> + <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"Холбогдсон (утас эсвэл медиа байхгүй), батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> + <string name="bluetooth_active_battery_level" msgid="3450745316700494425">"Идэвхтэй, батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_active_battery_level_untethered" msgid="2706188607604205362">"Идэвхтэй, Зүүн: Батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Баруун: Батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string> - <string name="bluetooth_battery_level" msgid="2893696778200201555">"Батерей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <string name="bluetooth_battery_level" msgid="2893696778200201555">"Батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"Зүүн: Батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Баруун: Батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string> <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Идэвхтэй"</string> <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Идэвхтэй, зөвхөн зүүн тал"</string> diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml index 083e55a7e1fc..3c7e5b3a883f 100644 --- a/packages/SettingsLib/res/values-my/strings.xml +++ b/packages/SettingsLib/res/values-my/strings.xml @@ -183,8 +183,8 @@ <string name="running_process_item_user_label" msgid="3988506293099805796">"အသုံးပြုသူ- <xliff:g id="USER_NAME">%1$s</xliff:g>"</string> <string name="launch_defaults_some" msgid="3631650616557252926">"မူရင်းအချို့ သတ်မှတ်ပြီး"</string> <string name="launch_defaults_none" msgid="8049374306261262709">"မူရင်း သတ်မှတ်မထားပါ။"</string> - <string name="tts_settings" msgid="8130616705989351312">"စာသားမှစကားပြောပြောင်း ဆက်တင်များ"</string> - <string name="tts_settings_title" msgid="7602210956640483039">"စာသားမှ စကားပြောသို့ အထွက်"</string> + <string name="tts_settings" msgid="8130616705989351312">"စာ-မှ-စကားပြောင်းခြင်း ဆက်တင်များ"</string> + <string name="tts_settings_title" msgid="7602210956640483039">"စာ-မှ-စကားသို့ အထွက်"</string> <string name="tts_default_rate_title" msgid="3964187817364304022">"စကားပြောနှုန်း"</string> <string name="tts_default_rate_summary" msgid="3781937042151716987">"စာတမ်းအားပြောဆိုသော အမြန်နှုန်း"</string> <string name="tts_default_pitch_title" msgid="6988592215554485479">"အသံအနိမ့်အမြင့်"</string> @@ -198,7 +198,7 @@ <string name="tts_install_data_title" msgid="1829942496472751703">"အသံဒေတာများကို ထည့်သွင်းခြင်း"</string> <string name="tts_install_data_summary" msgid="3608874324992243851">"စကားသံပေါင်းစပ်မှုအတွက်လိုအပ်သောအသံဒေတာအား ထည့်သွင်းမည်"</string> <string name="tts_engine_security_warning" msgid="3372432853837988146">"ဤစကားသံပေါင်းစပ်စနစ်အားအသုံးပြုရာရာတွင် သင့်ကိုယ်ရေးအချက်အလက်များဖြစ်သော စကားဝှက်များနှင့် ကရက်ဒစ်ကတ်နံပါတ်စသည်တို့အပါအဝင် သင်ပြောဆိုသောစာသားများအားလုံးကို ရယူသွားမည်ဖြစ်သည်။ ဤစနစ်သည် <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> မှ လာပါသည်။ ဤစကားသံပေါင်းစပ်စနစ်ကို အသုံးပြုမလား။"</string> - <string name="tts_engine_network_required" msgid="8722087649733906851">"ဤဘာသာစကားသည် စာသားမှ အသံထွက်ရန် အလုပ်လုပ်သော ကွန်ရက်ချိတ်ဆက်မှု လိုအပ်သည်။"</string> + <string name="tts_engine_network_required" msgid="8722087649733906851">"ဤဘာသာစကားသည် စာ-မှ-စကား ပြောင်းရန် အလုပ်လုပ်သော ကွန်ရက်ချိတ်ဆက်မှု လိုအပ်သည်။"</string> <string name="tts_default_sample_string" msgid="6388016028292967973">"ဤသည်မှာ အသံတုလုပ်ခြင်း ၏ နမူနာတစ်ခုဖြစ်သည်။"</string> <string name="tts_status_title" msgid="8190784181389278640">"လက်ရှိဘာသာစကားအခြေအနေ"</string> <string name="tts_status_ok" msgid="8583076006537547379">"<xliff:g id="LOCALE">%1$s</xliff:g> သည်အပြည့်အ၀ အထောက်အကူပြုသည်။"</string> diff --git a/packages/SettingsProvider/res/values-nb/strings.xml b/packages/SettingsProvider/res/values-nb/strings.xml index 3bdaf83a4230..8da90c0f32cb 100644 --- a/packages/SettingsProvider/res/values-nb/strings.xml +++ b/packages/SettingsProvider/res/values-nb/strings.xml @@ -20,6 +20,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4567566098528588863">"Lagring av innstillinger"</string> - <string name="wifi_softap_config_change" msgid="5688373762357941645">"Innstillingene for Wi-Fi-sone er endret"</string> + <string name="wifi_softap_config_change" msgid="5688373762357941645">"Innstillingene for wifi-sone er endret"</string> <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Trykk for å se detaljer"</string> </resources> diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 1c13b1660e31..6edf13addbca 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -618,6 +618,17 @@ android:excludeFromRecents="true" android:visibleToInstantApps="true"/> + <activity + android:name=".media.MediaProjectionAppSelectorActivity" + android:theme="@style/Theme.SystemUI.MediaProjectionAppSelector" + android:finishOnCloseSystemDialogs="true" + android:excludeFromRecents="true" + android:documentLaunchMode="never" + android:relinquishTaskIdentity="true" + android:configChanges= + "screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden" + android:visibleToInstantApps="true"/> + <!-- started from TvNotificationPanel --> <activity android:name=".statusbar.tv.notifications.TvNotificationPanelActivity" diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt index cb16d7c3471f..dbdbdf6ee2ba 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt @@ -150,15 +150,16 @@ constructor( fun showFromDialog( dialog: Dialog, animateFrom: Dialog, + cuj: DialogCuj? = null, animateBackgroundBoundsChange: Boolean = false ) { val view = openedDialogs.firstOrNull { it.dialog == animateFrom }?.dialogContentWithBackground ?: throw IllegalStateException( "The animateFrom dialog was not animated using " + - "DialogLaunchAnimator.showFrom(View|Dialog)" - ) - showFromView(dialog, view, animateBackgroundBoundsChange = animateBackgroundBoundsChange) + "DialogLaunchAnimator.showFrom(View|Dialog)") + showFromView( + dialog, view, animateBackgroundBoundsChange = animateBackgroundBoundsChange, cuj = cuj) } /** diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml index 8f8993f3c8d9..12dfa1042dd7 100644 --- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml +++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml @@ -59,26 +59,6 @@ </LinearLayout> - <com.android.systemui.statusbar.KeyguardAffordanceView - android:id="@+id/camera_button" - android:layout_height="@dimen/keyguard_affordance_height" - android:layout_width="@dimen/keyguard_affordance_width" - android:layout_gravity="bottom|end" - android:src="@drawable/ic_camera_alt_24dp" - android:scaleType="center" - android:contentDescription="@string/accessibility_camera_button" - android:tint="?attr/wallpaperTextColor" /> - - <com.android.systemui.statusbar.KeyguardAffordanceView - android:id="@+id/left_button" - android:layout_height="@dimen/keyguard_affordance_height" - android:layout_width="@dimen/keyguard_affordance_width" - android:layout_gravity="bottom|start" - android:src="@*android:drawable/ic_phone" - android:scaleType="center" - android:contentDescription="@string/accessibility_phone_button" - android:tint="?attr/wallpaperTextColor" /> - <ImageView android:id="@+id/wallet_button" android:layout_height="@dimen/keyguard_affordance_fixed_height" diff --git a/packages/SystemUI/res/layout/media_ttt_chip_receiver.xml b/packages/SystemUI/res/layout/media_ttt_chip_receiver.xml index 2b3d11b0e191..e079fd3c5e8f 100644 --- a/packages/SystemUI/res/layout/media_ttt_chip_receiver.xml +++ b/packages/SystemUI/res/layout/media_ttt_chip_receiver.xml @@ -21,6 +21,12 @@ android:layout_height="wrap_content" > + <com.android.systemui.media.taptotransfer.receiver.ReceiverChipRippleView + android:id="@+id/ripple" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + /> + <com.android.internal.widget.CachingIconView android:id="@+id/app_icon" android:layout_width="@dimen/media_ttt_icon_size_receiver" diff --git a/packages/SystemUI/res/layout/wireless_charging_layout.xml b/packages/SystemUI/res/layout/wireless_charging_layout.xml index 1312b413f106..887e3e715369 100644 --- a/packages/SystemUI/res/layout/wireless_charging_layout.xml +++ b/packages/SystemUI/res/layout/wireless_charging_layout.xml @@ -22,7 +22,7 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - <com.android.systemui.statusbar.charging.ChargingRippleView + <com.android.systemui.ripple.RippleView android:id="@+id/wireless_charging_ripple" android:layout_width="match_parent" android:layout_height="match_parent"/> diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index eff4e00fd07b..771973c36053 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -37,12 +37,6 @@ <item>400</item> </integer-array> - <!-- Show mic or phone affordance on Keyguard --> - <bool name="config_keyguardShowLeftAffordance">false</bool> - - <!-- Show camera affordance on Keyguard --> - <bool name="config_keyguardShowCameraAffordance">false</bool> - <!-- decay duration (from size_max -> size), in ms --> <integer name="navigation_bar_deadzone_hold">333</integer> <integer name="navigation_bar_deadzone_decay">333</integer> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 009a123de40c..13250c879d5d 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -671,9 +671,6 @@ <!-- The minimum background radius when swiping to a side for the camera / phone affordances. --> <dimen name="keyguard_affordance_min_background_radius">30dp</dimen> - <!-- The size of the touch targets on the keyguard for the affordances. --> - <dimen name="keyguard_affordance_touch_target_size">120dp</dimen> - <!-- The grow amount for the camera and phone circles when hinting --> <dimen name="hint_grow_amount_sideways">60dp</dimen> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 343ec4f67964..ef672f3a6213 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -313,13 +313,6 @@ <string name="accessibility_scanning_face">Scanning face</string> <!-- Click action label for accessibility for the smart reply buttons (not shown on-screen).". [CHAR LIMIT=NONE] --> <string name="accessibility_send_smart_reply">Send</string> - <!-- Content description of the manage notification button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] --> - <!-- Click action label for accessibility for the phone button. [CHAR LIMIT=NONE] --> - <string name="phone_label">open phone</string> - <!-- Click action label for accessibility for the voice assist button. This is not shown on-screen and is an accessibility label for the icon which launches the voice assist from the lock screen.[CHAR LIMIT=NONE] --> - <string name="voice_assist_label">open voice assist</string> - <!-- Click action label for accessibility for the phone button. [CHAR LIMIT=NONE] --> - <string name="camera_label">open camera</string> <!-- Button name for "Cancel". [CHAR LIMIT=NONE] --> <string name="cancel">Cancel</string> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index 758c16d15bcf..22279785a773 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -265,6 +265,10 @@ <style name="Animation.ShutdownUi" parent="@android:style/Animation.Toast"> </style> + <style name="Theme.SystemUI.MediaProjectionAppSelector" + parent="@*android:style/Theme.DeviceDefault.Chooser"> + </style> + <!-- Standard animations for hiding and showing the status bar. --> <style name="Theme.SystemUI" parent="@*android:style/Theme.DeviceDefault.SystemUI"> diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestRule.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestRule.kt index 363ce10fa36c..564901c2a773 100644 --- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestRule.kt +++ b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestRule.kt @@ -20,6 +20,7 @@ import android.app.UiModeManager import android.content.Context import android.graphics.Bitmap import android.graphics.Canvas +import android.os.Build import android.os.UserHandle import android.view.Display import android.view.View @@ -32,6 +33,7 @@ import platform.test.screenshot.GoldenImagePathManager import platform.test.screenshot.PathConfig import platform.test.screenshot.PathElementNoContext import platform.test.screenshot.ScreenshotTestRule +import platform.test.screenshot.matchers.MSSIMMatcher import platform.test.screenshot.matchers.PixelPerfectMatcher /** @@ -55,7 +57,11 @@ class ScreenshotTestRule(private val testSpec: ScreenshotTestSpec) : TestRule { currentDisplay?.name ?: error("currentDisplay is null") }, ) - private val defaultMatcher = PixelPerfectMatcher() + private val matcher = if (shouldUsePerfectMatching()) { + PixelPerfectMatcher() + } else { + MSSIMMatcher() + } private val screenshotRule = ScreenshotTestRule( @@ -67,6 +73,17 @@ class ScreenshotTestRule(private val testSpec: ScreenshotTestSpec) : TestRule { ) ) + private fun shouldUsePerfectMatching(): Boolean { + // Different CPU architectures can sometimes end up rendering differently, so we can't do + // pixel-perfect matching on different architectures using the same golden. Given that our + // presubmits are run on cf_x86_64_phone, our goldens should be perfectly matched on the + // x86_64 architecture and use the Structural Similarity Index on others. + // TODO(b/237511747): Run our screenshot presubmit tests on arm64 instead so that we can + // do pixel perfect matching both at presubmit time and at development time with actual + // devices. + return Build.CPU_ABI == "x86_64" + } + override fun apply(base: Statement, description: Description): Statement { // The statement which call beforeTest() before running the test and afterTest() afterwards. val statement = @@ -147,7 +164,7 @@ class ScreenshotTestRule(private val testSpec: ScreenshotTestSpec) : TestRule { // device to assertBitmapAgainstGolden instead? currentDisplay = testSpec.display currentGoldenIdentifier = goldenIdentifier - screenshotRule.assertBitmapAgainstGolden(bitmap, identifierWithSpec, defaultMatcher) + screenshotRule.assertBitmapAgainstGolden(bitmap, identifierWithSpec, matcher) currentDisplay = null currentGoldenIdentifier = goldenIdentifier } diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt index 35812e39677d..6a80c486d515 100644 --- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt +++ b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt @@ -60,11 +60,17 @@ class ViewScreenshotTestRule(testSpec: ScreenshotTestSpec) : TestRule { ) { var dialog: Dialog? = null activityRule.scenario.onActivity { activity -> - // Make sure that the dialog draws full screen and fits the whole display instead of the - // system bars. dialog = dialogProvider(activity).apply { + // Make sure that the dialog draws full screen and fits the whole display + // instead of the system bars. window.setDecorFitsSystemWindows(false) + + // Disable enter/exit animations. + create() + window.setWindowAnimations(0) + + // Show the dialog. show() } } @@ -74,7 +80,11 @@ class ViewScreenshotTestRule(testSpec: ScreenshotTestSpec) : TestRule { activityRule.scenario.onActivity { // Check that the content is what we expected. val dialog = dialog ?: error("dialog is null") - screenshotRule.screenshotTest(goldenIdentifier, dialog.window.decorView) + try { + screenshotRule.screenshotTest(goldenIdentifier, dialog.window.decorView) + } finally { + dialog.dismiss() + } } } } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index a783e1c6f9ce..de5de32168e7 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -3627,6 +3627,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab mHandler.sendEmptyMessage(MSG_KEYGUARD_DISMISS_ANIMATION_FINISHED); } + /** + * @return true when the screen is on (including when a screensaver is showing), + * false when the screen is OFF or DOZE (including showing AOD UI) + */ public boolean isDeviceInteractive() { return mDeviceInteractive; } @@ -3769,6 +3773,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab pw.println(" mFingerprintLockedOut=" + mFingerprintLockedOut); pw.println(" mFingerprintLockedOutPermanent=" + mFingerprintLockedOutPermanent); pw.println(" enabledByUser=" + mBiometricEnabledForUser.get(userId)); + pw.println(" mKeyguardOccluded=" + mKeyguardOccluded); + pw.println(" mIsDreaming=" + mIsDreaming); if (isUdfpsSupported()) { pw.println(" udfpsEnrolled=" + isUdfpsEnrolled()); pw.println(" shouldListenForUdfps=" + shouldListenForFingerprint(true)); diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java index c1b2aba22b57..43e737823692 100644 --- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java @@ -23,7 +23,6 @@ import static com.android.keyguard.LockIconView.ICON_LOCK; import static com.android.keyguard.LockIconView.ICON_UNLOCK; import static com.android.systemui.classifier.Classifier.LOCK_ICON; import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset; -import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInProgressOffset; import android.content.res.Configuration; import android.content.res.Resources; @@ -403,7 +402,6 @@ public class LockIconViewController extends ViewController<LockIconView> impleme float offsetY = MathUtils.lerp(0f, getBurnInOffset(mMaxBurnInOffsetY * 2, false /* xAxis */) - mMaxBurnInOffsetY, mInterpolatedDarkAmount); - float progress = MathUtils.lerp(0f, getBurnInProgressOffset(), mInterpolatedDarkAmount); mView.setTranslationX(offsetX); mView.setTranslationY(offsetY); diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt index 378ae14f0327..fef7383634f0 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt @@ -29,8 +29,7 @@ import android.view.View import android.view.animation.PathInterpolator import com.android.internal.graphics.ColorUtils import com.android.systemui.animation.Interpolators -import com.android.systemui.statusbar.charging.DwellRippleShader -import com.android.systemui.statusbar.charging.RippleShader +import com.android.systemui.ripple.RippleShader private const val RIPPLE_SPARKLE_STRENGTH: Float = 0.4f @@ -298,7 +297,7 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at addListener(object : AnimatorListenerAdapter() { override fun onAnimationStart(animation: Animator?) { unlockedRippleInProgress = true - rippleShader.shouldFadeOutRipple = true + rippleShader.rippleFill = false drawRipple = true visibility = VISIBLE } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/charging/DwellRippleShader.kt b/packages/SystemUI/src/com/android/systemui/biometrics/DwellRippleShader.kt index 236129f8eb50..979fe33fb25b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/charging/DwellRippleShader.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/DwellRippleShader.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.statusbar.charging +package com.android.systemui.biometrics import android.graphics.PointF import android.graphics.RuntimeShader diff --git a/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt b/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt new file mode 100644 index 000000000000..4986fe85af19 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt @@ -0,0 +1,156 @@ +/* + * 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.camera + +import android.app.ActivityManager +import android.app.ActivityManager.RunningTaskInfo +import android.app.ActivityOptions +import android.app.ActivityTaskManager +import android.content.ContentResolver +import android.content.Context +import android.content.Intent +import android.content.pm.PackageManager +import android.content.pm.ResolveInfo +import android.os.AsyncTask +import android.os.RemoteException +import android.os.UserHandle +import android.util.Log +import android.view.WindowManager +import com.android.keyguard.KeyguardUpdateMonitor +import com.android.systemui.ActivityIntentHelper +import com.android.systemui.camera.CameraIntents.Companion.isSecureCameraIntent +import com.android.systemui.plugins.ActivityStarter +import com.android.systemui.statusbar.StatusBarState +import com.android.systemui.statusbar.phone.CentralSurfaces +import com.android.systemui.statusbar.phone.PanelViewController +import com.android.systemui.statusbar.policy.KeyguardStateController +import javax.inject.Inject + +/** + * Helps with handling camera-related gestures (for example, double-tap the power button to launch + * the camera). + */ +class CameraGestureHelper @Inject constructor( + private val context: Context, + private val centralSurfaces: CentralSurfaces, + private val keyguardStateController: KeyguardStateController, + private val packageManager: PackageManager, + private val activityManager: ActivityManager, + private val activityStarter: ActivityStarter, + private val activityIntentHelper: ActivityIntentHelper, + private val cameraIntents: CameraIntentsWrapper, + private val contentResolver: ContentResolver, +) { + /** + * Whether the camera application can be launched for the camera launch gesture. + */ + fun canCameraGestureBeLaunched(statusBarState: Int): Boolean { + if (!centralSurfaces.isCameraAllowedByAdmin) { + return false + } + + val resolveInfo: ResolveInfo = packageManager.resolveActivityAsUser( + getStartCameraIntent(), + PackageManager.MATCH_DEFAULT_ONLY, + KeyguardUpdateMonitor.getCurrentUser() + ) + val resolvedPackage = resolveInfo.activityInfo?.packageName + return (resolvedPackage != null && + (statusBarState != StatusBarState.SHADE || + !isForegroundApp(resolvedPackage))) + } + + /** + * Launches the camera. + * + * @param source The source of the camera launch, to be passed to the camera app via [Intent] + */ + fun launchCamera(source: Int) { + val intent: Intent = getStartCameraIntent() + intent.putExtra(EXTRA_CAMERA_LAUNCH_SOURCE, source) + val wouldLaunchResolverActivity = activityIntentHelper.wouldLaunchResolverActivity( + intent, KeyguardUpdateMonitor.getCurrentUser() + ) + if (isSecureCameraIntent(intent) && !wouldLaunchResolverActivity) { + AsyncTask.execute { + // Normally an activity will set its requested rotation animation on its window. + // However when launching an activity causes the orientation to change this is too + // late. In these cases, the default animation is used. This doesn't look good for + // the camera (as it rotates the camera contents out of sync with physical reality). + // Therefore, we ask the WindowManager to force the cross-fade animation if an + // orientation change happens to occur during the launch. + val activityOptions = ActivityOptions.makeBasic() + activityOptions.setDisallowEnterPictureInPictureWhileLaunching(true) + activityOptions.rotationAnimationHint = + WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS + try { + ActivityTaskManager.getService().startActivityAsUser( + null, + context.basePackageName, + context.attributionTag, + intent, + intent.resolveTypeIfNeeded(contentResolver), + null, + null, + 0, + Intent.FLAG_ACTIVITY_NEW_TASK, + null, + activityOptions.toBundle(), + UserHandle.CURRENT.identifier, + ) + } catch (e: RemoteException) { + Log.w( + PanelViewController.TAG, + "Unable to start camera activity", + e + ) + } + } + } else { + // We need to delay starting the activity because ResolverActivity finishes itself if + // launched from behind the lock-screen. + activityStarter.startActivity(intent, false /* dismissShade */) + } + } + + /** + * Returns an [Intent] that can be used to start the camera app such that it occludes the + * lock-screen, if needed. + */ + private fun getStartCameraIntent(): Intent { + val isLockScreenDismissible = keyguardStateController.canDismissLockScreen() + val isSecure = keyguardStateController.isMethodSecure + return if (isSecure && !isLockScreenDismissible) { + cameraIntents.getSecureCameraIntent() + } else { + cameraIntents.getInsecureCameraIntent() + } + } + + /** + * Returns `true` if the application with the given package name is running in the foreground; + * `false` otherwise + */ + private fun isForegroundApp(packageName: String): Boolean { + val tasks: List<RunningTaskInfo> = activityManager.getRunningTasks(1) + return tasks.isNotEmpty() && packageName == tasks[0].topActivity.packageName + } + + companion object { + private const val EXTRA_CAMERA_LAUNCH_SOURCE = "com.android.systemui.camera_launch_source" + } +} diff --git a/packages/SystemUI/src/com/android/systemui/camera/CameraIntentsWrapper.kt b/packages/SystemUI/src/com/android/systemui/camera/CameraIntentsWrapper.kt new file mode 100644 index 000000000000..cf02f8fb4a3c --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/camera/CameraIntentsWrapper.kt @@ -0,0 +1,43 @@ +/* + * 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.camera + +import android.content.Context +import android.content.Intent +import javax.inject.Inject + +/** Injectable wrapper around [CameraIntents]. */ +class CameraIntentsWrapper @Inject constructor( + private val context: Context, +) { + + /** + * Returns an [Intent] that can be used to start the camera, suitable for when the device is + * already unlocked + */ + fun getSecureCameraIntent(): Intent { + return CameraIntents.getSecureCameraIntent(context) + } + + /** + * Returns an [Intent] that can be used to start the camera, suitable for when the device is not + * already unlocked + */ + fun getInsecureCameraIntent(): Intent { + return CameraIntents.getInsecureCameraIntent(context) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/charging/WiredChargingRippleController.kt b/packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt index 558bcac681d9..8292e52b1ffd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/charging/WiredChargingRippleController.kt +++ b/packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.statusbar.charging +package com.android.systemui.charging import android.content.Context import android.content.res.Configuration @@ -32,6 +32,7 @@ import com.android.systemui.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags +import com.android.systemui.ripple.RippleView import com.android.systemui.statusbar.commandline.Command import com.android.systemui.statusbar.commandline.CommandRegistry import com.android.systemui.statusbar.policy.BatteryController @@ -84,7 +85,7 @@ class WiredChargingRippleController @Inject constructor( private var debounceLevel = 0 @VisibleForTesting - var rippleView: ChargingRippleView = ChargingRippleView(context, attrs = null) + var rippleView: RippleView = RippleView(context, attrs = null) init { pluggedIn = batteryController.isPluggedIn diff --git a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java index 0d3e2ae9a776..f6368ee19e8f 100644 --- a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java +++ b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java @@ -34,7 +34,7 @@ import android.widget.TextView; import com.android.settingslib.Utils; import com.android.systemui.R; import com.android.systemui.animation.Interpolators; -import com.android.systemui.statusbar.charging.ChargingRippleView; +import com.android.systemui.ripple.RippleView; import java.text.NumberFormat; @@ -46,7 +46,7 @@ public class WirelessChargingLayout extends FrameLayout { private static final long RIPPLE_ANIMATION_DURATION = 1500; private static final int SCRIM_COLOR = 0x4C000000; private static final int SCRIM_FADE_DURATION = 300; - private ChargingRippleView mRippleView; + private RippleView mRippleView; public WirelessChargingLayout(Context context) { super(context); diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java index ba1e057716f8..137e28888728 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java @@ -43,6 +43,7 @@ import com.android.systemui.flags.FlagsModule; import com.android.systemui.fragments.FragmentService; import com.android.systemui.log.dagger.LogModule; import com.android.systemui.lowlightclock.LowLightClockController; +import com.android.systemui.media.dagger.MediaProjectionModule; import com.android.systemui.model.SysUiState; import com.android.systemui.navigationbar.NavigationBarComponent; import com.android.systemui.plugins.BcSmartspaceDataPlugin; @@ -119,6 +120,7 @@ import dagger.Provides; FalsingModule.class, FlagsModule.class, LogModule.class, + MediaProjectionModule.class, PeopleHubModule.class, PluginModule.class, PrivacyModule.class, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java index 95b3b3f6452f..3eb3c80f4081 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java @@ -453,6 +453,8 @@ public class KeyguardService extends Service { @Override // Binder interface public void setOccluded(boolean isOccluded, boolean animate) { + Log.d(TAG, "setOccluded(" + isOccluded + ")"); + Trace.beginSection("KeyguardService.mBinder#setOccluded"); checkPermission(); mKeyguardViewMediator.setOccluded(isOccluded, animate); diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index f1d3653050fe..7abf2a8241bb 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -837,9 +837,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, private final ActivityLaunchAnimator.Controller mOccludeAnimationController = new ActivityLaunchAnimator.Controller() { @Override - public void onLaunchAnimationStart(boolean isExpandingFullyAbove) { - setOccluded(true /* occluded */, false /* animate */); - } + public void onLaunchAnimationStart(boolean isExpandingFullyAbove) {} @Override public void onLaunchAnimationCancelled() { @@ -925,6 +923,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps, IRemoteAnimationFinishedCallback finishedCallback) throws RemoteException { + Log.d(TAG, "UnoccludeAnimator#onAnimationStart. Set occluded = false."); setOccluded(false /* isOccluded */, true /* animate */); if (apps == null || apps.length == 0 || apps[0] == null) { @@ -1676,6 +1675,8 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, * Notify us when the keyguard is occluded by another window */ public void setOccluded(boolean isOccluded, boolean animate) { + Log.d(TAG, "setOccluded(" + isOccluded + ")"); + Trace.beginSection("KeyguardViewMediator#setOccluded"); if (DEBUG) Log.d(TAG, "setOccluded " + isOccluded); mInteractionJankMonitor.cancel(CUJ_LOCKSCREEN_TRANSITION_FROM_AOD); @@ -1706,6 +1707,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, */ private void handleSetOccluded(boolean isOccluded, boolean animate) { Trace.beginSection("KeyguardViewMediator#handleSetOccluded"); + Log.d(TAG, "handleSetOccluded(" + isOccluded + ")"); synchronized (KeyguardViewMediator.this) { if (mHiding && isOccluded) { // We're in the process of going away but WindowManager wants to show a @@ -2699,7 +2701,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, /** Hides the surface behind the keyguard by re-showing the keyguard/activity lock screen. */ public void hideSurfaceBehindKeyguard() { mSurfaceBehindRemoteAnimationRequested = false; - + mKeyguardStateController.notifyKeyguardGoingAway(false); if (mShowing) { setShowingLocked(true, true); } @@ -3207,16 +3209,18 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, // internal state to reflect that immediately, vs. waiting for the launch animator to // begin. Otherwise, calls to setShowingLocked, etc. will not know that we're about to // be occluded and might re-show the keyguard. + Log.d(TAG, "OccludeAnimator#onAnimationStart. Set occluded = true."); setOccluded(true /* isOccluded */, false /* animate */); } @Override public void onAnimationCancelled(boolean isKeyguardOccluded) throws RemoteException { super.onAnimationCancelled(isKeyguardOccluded); - setOccluded(isKeyguardOccluded /* occluded */, false /* animate */); Log.d(TAG, "Occlude animation cancelled by WM. " - + "Setting occluded state to: " + mOccluded); + + "Setting occluded state to: " + isKeyguardOccluded); + setOccluded(isKeyguardOccluded /* occluded */, false /* animate */); + } } } diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt new file mode 100644 index 000000000000..6802da347c93 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2022 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.media + +import android.app.ActivityOptions +import android.content.Intent +import android.media.projection.IMediaProjection +import android.media.projection.MediaProjectionManager.EXTRA_MEDIA_PROJECTION +import android.os.Binder +import android.os.Bundle +import android.os.IBinder +import android.view.View +import com.android.internal.app.ChooserActivity +import com.android.internal.app.chooser.NotSelectableTargetInfo +import com.android.internal.app.chooser.TargetInfo +import com.android.systemui.util.AsyncActivityLauncher +import com.android.systemui.R; +import javax.inject.Inject + +class MediaProjectionAppSelectorActivity @Inject constructor( + private val activityLauncher: AsyncActivityLauncher +) : ChooserActivity() { + + public override fun onCreate(bundle: Bundle?) { + val queryIntent = Intent(Intent.ACTION_MAIN) + .addCategory(Intent.CATEGORY_LAUNCHER) + intent.putExtra(Intent.EXTRA_INTENT, queryIntent) + + // TODO(b/235465652) Use resource lexeme + intent.putExtra(Intent.EXTRA_TITLE, "Record or cast an app") + + super.onCreate(bundle) + + // TODO(b/235465652) we should update VisD of the title and add an icon + findViewById<View>(R.id.title)?.visibility = View.VISIBLE + } + + override fun appliedThemeResId(): Int = + R.style.Theme_SystemUI_MediaProjectionAppSelector + + override fun startSelected(which: Int, always: Boolean, filtered: Boolean) { + val currentListAdapter = mChooserMultiProfilePagerAdapter.activeListAdapter + val targetInfo = currentListAdapter.targetInfoForPosition(which, filtered) ?: return + if (targetInfo is NotSelectableTargetInfo) return + + val intent = createIntent(targetInfo) + + val launchToken: IBinder = Binder("media_projection_launch_token") + val activityOptions = ActivityOptions.makeBasic() + activityOptions.launchCookie = launchToken + + val userHandle = mMultiProfilePagerAdapter.activeListAdapter.userHandle + + // Launch activity asynchronously and wait for the result, launching of an activity + // is typically very fast, so we don't show any loaders. + // We wait for the activity to be launched to make sure that the window of the activity + // is created and ready to be captured. + val activityStarted = activityLauncher + .startActivityAsUser(intent, userHandle, activityOptions.toBundle()) { + onTargetActivityLaunched(launchToken) + } + + // Rely on the ActivityManager to pop up a dialog regarding app suspension + // and return false if suspended + if (!targetInfo.isSuspended && activityStarted) { + // TODO(b/222078415) track activity launch + } + } + + private fun createIntent(target: TargetInfo): Intent { + val intent = Intent(target.resolvedIntent) + + // Launch the app in a new task, so it won't be in the host's app task + intent.flags = intent.flags or Intent.FLAG_ACTIVITY_NEW_TASK + + // Remove activity forward result flag as this activity will + // return the media projection session + intent.flags = intent.flags and Intent.FLAG_ACTIVITY_FORWARD_RESULT.inv() + + return intent + } + + override fun onDestroy() { + activityLauncher.destroy() + super.onDestroy() + } + + override fun onActivityStarted(cti: TargetInfo) { + // do nothing + } + + private fun onTargetActivityLaunched(launchToken: IBinder) { + val mediaProjectionBinder = intent.getIBinderExtra(EXTRA_MEDIA_PROJECTION) + val projection = IMediaProjection.Stub.asInterface(mediaProjectionBinder) + + projection.launchCookie = launchToken + + val intent = Intent() + intent.putExtra(EXTRA_MEDIA_PROJECTION, projection.asBinder()) + setResult(RESULT_OK, intent) + setForceSendResultForMediaProjection() + finish() + } + + override fun shouldGetOnlyDefaultActivities() = false +} diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java index 38604091c409..397bffcaa64c 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java +++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java @@ -40,7 +40,10 @@ import android.text.style.StyleSpan; import android.util.Log; import android.view.Window; +import com.android.systemui.Dependency; import com.android.systemui.R; +import com.android.systemui.flags.FeatureFlags; +import com.android.systemui.flags.Flags; import com.android.systemui.statusbar.phone.SystemUIDialog; import com.android.systemui.util.Utils; @@ -53,6 +56,7 @@ public class MediaProjectionPermissionActivity extends Activity private String mPackageName; private int mUid; private IMediaProjectionManager mService; + private FeatureFlags mFeatureFlags; private AlertDialog mDialog; @@ -60,6 +64,7 @@ public class MediaProjectionPermissionActivity extends Activity public void onCreate(Bundle icicle) { super.onCreate(icicle); + mFeatureFlags = Dependency.get(FeatureFlags.class); mPackageName = getCallingPackage(); IBinder b = ServiceManager.getService(MEDIA_PROJECTION_SERVICE); mService = IMediaProjectionManager.Stub.asInterface(b); @@ -141,14 +146,22 @@ public class MediaProjectionPermissionActivity extends Activity dialogTitle = getString(R.string.media_projection_dialog_title, appName); } - mDialog = new AlertDialog.Builder(this, R.style.Theme_SystemUI_Dialog) + AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this, + R.style.Theme_SystemUI_Dialog) .setTitle(dialogTitle) .setIcon(R.drawable.ic_media_projection_permission) .setMessage(dialogText) .setPositiveButton(R.string.media_projection_action_text, this) .setNeutralButton(android.R.string.cancel, this) - .setOnCancelListener(this) - .create(); + .setOnCancelListener(this); + + if (isPartialScreenSharingEnabled()) { + // This is a temporary entry point before we have a new permission dialog + // TODO(b/233183090): this activity should be redesigned to have a dropdown selector + dialogBuilder.setNegativeButton("App", this); + } + + mDialog = dialogBuilder.create(); SystemUIDialog.registerDismissListener(mDialog); SystemUIDialog.applyFlags(mDialog); @@ -177,6 +190,15 @@ public class MediaProjectionPermissionActivity extends Activity if (which == AlertDialog.BUTTON_POSITIVE) { setResult(RESULT_OK, getMediaProjectionIntent(mUid, mPackageName)); } + + if (isPartialScreenSharingEnabled() && which == AlertDialog.BUTTON_NEGATIVE) { + IMediaProjection projection = createProjection(mUid, mPackageName); + final Intent intent = new Intent(this, MediaProjectionAppSelectorActivity.class); + intent.putExtra(MediaProjectionManager.EXTRA_MEDIA_PROJECTION, + projection.asBinder()); + intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); + startActivity(intent); + } } catch (RemoteException e) { Log.e(TAG, "Error granting projection permission", e); setResult(RESULT_CANCELED); @@ -188,10 +210,14 @@ public class MediaProjectionPermissionActivity extends Activity } } + private IMediaProjection createProjection(int uid, String packageName) throws RemoteException { + return mService.createProjection(uid, packageName, + MediaProjectionManager.TYPE_SCREEN_CAPTURE, false /* permanentGrant */); + } + private Intent getMediaProjectionIntent(int uid, String packageName) throws RemoteException { - IMediaProjection projection = mService.createProjection(uid, packageName, - MediaProjectionManager.TYPE_SCREEN_CAPTURE, false /* permanentGrant */); + IMediaProjection projection = createProjection(uid, packageName); Intent intent = new Intent(); intent.putExtra(MediaProjectionManager.EXTRA_MEDIA_PROJECTION, projection.asBinder()); return intent; @@ -201,4 +227,8 @@ public class MediaProjectionPermissionActivity extends Activity public void onCancel(DialogInterface dialog) { finish(); } + + private boolean isPartialScreenSharingEnabled() { + return mFeatureFlags.isEnabled(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING); + } } diff --git a/packages/SystemUI/src/com/android/systemui/media/dagger/MediaProjectionModule.kt b/packages/SystemUI/src/com/android/systemui/media/dagger/MediaProjectionModule.kt new file mode 100644 index 000000000000..e33a1b909d48 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/media/dagger/MediaProjectionModule.kt @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2022 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.media.dagger + +import android.app.Activity +import com.android.systemui.media.MediaProjectionAppSelectorActivity +import dagger.Binds +import dagger.Module +import dagger.multibindings.ClassKey +import dagger.multibindings.IntoMap + +@Module +abstract class MediaProjectionModule { + + @Binds + @IntoMap + @ClassKey(MediaProjectionAppSelectorActivity::class) + abstract fun provideMediaProjectionAppSelectorActivity( + activity: MediaProjectionAppSelectorActivity): Activity + +} diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt index 0f1cdcc3fa5b..c9fce794f57f 100644 --- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt @@ -54,7 +54,7 @@ import com.android.systemui.util.view.ViewUtil abstract class MediaTttChipControllerCommon<T : ChipInfoCommon>( internal val context: Context, internal val logger: MediaTttLogger, - private val windowManager: WindowManager, + internal val windowManager: WindowManager, private val viewUtil: ViewUtil, @Main private val mainExecutor: DelayableExecutor, private val accessibilityManager: AccessibilityManager, diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt index f9818f0ad8be..99a5b8b2d450 100644 --- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt @@ -16,8 +16,10 @@ package com.android.systemui.media.taptotransfer.receiver +import android.annotation.SuppressLint import android.app.StatusBarManager import android.content.Context +import android.graphics.PointF import android.graphics.drawable.Drawable import android.graphics.drawable.Icon import android.media.MediaRoute2Info @@ -29,6 +31,8 @@ import android.view.View import android.view.ViewGroup import android.view.WindowManager import android.view.accessibility.AccessibilityManager +import androidx.core.graphics.ColorUtils +import com.android.settingslib.Utils import com.android.systemui.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main @@ -72,9 +76,15 @@ class MediaTttChipControllerReceiver @Inject constructor( powerManager, R.layout.media_ttt_chip_receiver ) { + @SuppressLint("WrongConstant") // We're allowed to use LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS override val windowLayoutParams = commonWindowLayoutParams.apply { - height = getWindowHeight() gravity = Gravity.BOTTOM.or(Gravity.CENTER_HORIZONTAL) + // Params below are needed for the ripple to work correctly + width = WindowManager.LayoutParams.MATCH_PARENT + height = WindowManager.LayoutParams.MATCH_PARENT + layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS + fitInsetsTypes = 0 // Ignore insets from all system bars + flags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE } private val commandQueueCallbacks = object : CommandQueue.Callbacks { @@ -149,7 +159,7 @@ class MediaTttChipControllerReceiver @Inject constructor( .alpha(1f) .setDuration(5.frames) .start() - + startRipple(chipView.requireViewById(R.id.ripple)) } override fun getIconSize(isAppIcon: Boolean): Int? = @@ -161,16 +171,44 @@ class MediaTttChipControllerReceiver @Inject constructor( } ) - private fun getWindowHeight(): Int { - return context.resources.getDimensionPixelSize(R.dimen.media_ttt_icon_size_receiver) + - // Make the window large enough to accommodate the animation amount - getTranslationAmount() - } - /** Returns the amount that the chip will be translated by in its intro animation. */ private fun getTranslationAmount(): Int { return context.resources.getDimensionPixelSize(R.dimen.media_ttt_receiver_vert_translation) } + + private fun startRipple(rippleView: ReceiverChipRippleView) { + if (rippleView.rippleInProgress) { + // Skip if ripple is still playing + return + } + rippleView.addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener { + override fun onViewDetachedFromWindow(view: View?) {} + + override fun onViewAttachedToWindow(view: View?) { + if (view == null) { + return + } + val attachedRippleView = view as ReceiverChipRippleView + layoutRipple(attachedRippleView) + attachedRippleView.startRipple() + attachedRippleView.removeOnAttachStateChangeListener(this) + } + }) + } + + private fun layoutRipple(rippleView: ReceiverChipRippleView) { + val windowBounds = windowManager.currentWindowMetrics.bounds + val height = windowBounds.height() + val width = windowBounds.width() + + rippleView.radius = height / 5f + // Center the ripple on the bottom of the screen in the middle. + rippleView.origin = PointF(/* x= */ width / 2f, /* y= */ height.toFloat()) + + val color = Utils.getColorAttrDefaultColor(context, R.attr.wallpaperTextColorAccent) + val colorWithAlpha = ColorUtils.setAlphaComponent(color, 70) + rippleView.setColor(colorWithAlpha) + } } data class ChipReceiverInfo( diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt new file mode 100644 index 000000000000..fed546bf52c2 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2022 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.media.taptotransfer.receiver + +import android.content.Context +import android.util.AttributeSet +import com.android.systemui.ripple.RippleView + +/** + * An expanding ripple effect for the media tap-to-transfer receiver chip. + */ +class ReceiverChipRippleView( + context: Context?, attrs: AttributeSet? +) : RippleView(context, attrs) { + init { + setRippleFill(true) + duration = 3000L + } +} diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java index 730f88ab9f8f..5f52485a5481 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java @@ -105,6 +105,7 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.internal.statusbar.LetterboxDetails; import com.android.internal.util.LatencyTracker; import com.android.internal.view.AppearanceRegion; import com.android.systemui.Gefingerpoken; @@ -1069,7 +1070,8 @@ public class NavigationBar extends ViewController<NavigationBarView> implements @Override public void onSystemBarAttributesChanged(int displayId, @Appearance int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, - @Behavior int behavior, InsetsVisibilities requestedVisibilities, String packageName) { + @Behavior int behavior, InsetsVisibilities requestedVisibilities, String packageName, + LetterboxDetails[] letterboxDetails) { if (displayId != mDisplayId) { return; } diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java index 1abf9903c08d..9e0c49641e72 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java @@ -57,6 +57,7 @@ import android.view.WindowInsetsController.Behavior; import androidx.annotation.NonNull; +import com.android.internal.statusbar.LetterboxDetails; import com.android.internal.view.AppearanceRegion; import com.android.systemui.Dumpable; import com.android.systemui.dagger.SysUISingleton; @@ -357,7 +358,8 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, @Override public void onSystemBarAttributesChanged(int displayId, int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, int behavior, - InsetsVisibilities requestedVisibilities, String packageName) { + InsetsVisibilities requestedVisibilities, String packageName, + LetterboxDetails[] letterboxDetails) { mOverviewProxyService.onSystemBarAttributesChanged(displayId, behavior); boolean nbModeChanged = false; if (mAppearance != appearance) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt b/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt index 260a3714a368..bdcc6b0b2a57 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt @@ -128,15 +128,16 @@ class UserSwitchDialogController @VisibleForTesting constructor( private val animateFrom: Dialog, private val dialogLaunchAnimator: DialogLaunchAnimator ) : DialogInterface by animateFrom, DialogShower { - override fun showDialog(dialog: Dialog) { + override fun showDialog(dialog: Dialog, cuj: DialogCuj) { dialogLaunchAnimator.showFromDialog( dialog, - animateFrom = animateFrom + animateFrom = animateFrom, + cuj ) } } interface DialogShower : DialogInterface { - fun showDialog(dialog: Dialog) + fun showDialog(dialog: Dialog, cuj: DialogCuj) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/charging/RippleShader.kt b/packages/SystemUI/src/com/android/systemui/ripple/RippleShader.kt index bdad36c58480..93a2efc4e96d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/charging/RippleShader.kt +++ b/packages/SystemUI/src/com/android/systemui/ripple/RippleShader.kt @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.android.systemui.statusbar.charging +package com.android.systemui.ripple import android.graphics.PointF import android.graphics.RuntimeShader @@ -148,7 +148,7 @@ class RippleShader internal constructor() : RuntimeShader(SHADER) { val fadeOutNoise = subProgress(0.4f, 1f, value) var fadeOutRipple = 0f var fadeCircle = 0f - if (shouldFadeOutRipple) { + if (!rippleFill) { fadeCircle = subProgress(0f, 0.2f, value) fadeOutRipple = subProgress(0.3f, 1f, value) } @@ -202,5 +202,9 @@ class RippleShader internal constructor() : RuntimeShader(SHADER) { setFloatUniform("in_pixelDensity", value) } - var shouldFadeOutRipple: Boolean = true + /** + * True if the ripple should stayed filled in as it expands to give a filled-in circle effect. + * False for a ring effect. + */ + var rippleFill: Boolean = false } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/charging/ChargingRippleView.kt b/packages/SystemUI/src/com/android/systemui/ripple/RippleView.kt index 10e90fee1469..fc52464ecf85 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/charging/ChargingRippleView.kt +++ b/packages/SystemUI/src/com/android/systemui/ripple/RippleView.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.statusbar.charging +package com.android.systemui.ripple import android.animation.Animator import android.animation.AnimatorListenerAdapter @@ -30,9 +30,10 @@ import android.view.View private const val RIPPLE_SPARKLE_STRENGTH: Float = 0.3f /** - * Expanding ripple effect that shows when charging begins. + * A generic expanding ripple effect. To trigger the ripple expansion, set [radius] and [origin], + * then call [startRipple]. */ -class ChargingRippleView(context: Context?, attrs: AttributeSet?) : View(context, attrs) { +open class RippleView(context: Context?, attrs: AttributeSet?) : View(context, attrs) { private val rippleShader = RippleShader() private val defaultColor: Int = 0xffffffff.toInt() private val ripplePaint = Paint() @@ -74,9 +75,9 @@ class ChargingRippleView(context: Context?, attrs: AttributeSet?) : View(context } val animator = ValueAnimator.ofFloat(0f, 1f) animator.duration = duration - animator.addUpdateListener { animator -> - val now = animator.currentPlayTime - val progress = animator.animatedValue as Float + animator.addUpdateListener { updateListener -> + val now = updateListener.currentPlayTime + val progress = updateListener.animatedValue as Float rippleShader.progress = progress rippleShader.distortionStrength = 1 - progress rippleShader.time = now.toFloat() @@ -92,10 +93,20 @@ class ChargingRippleView(context: Context?, attrs: AttributeSet?) : View(context rippleInProgress = true } + /** Set the color to be used for the ripple. */ fun setColor(color: Int) { rippleShader.color = color } + /** + * Set whether the ripple should remain filled as the ripple expands. + * + * See [RippleShader.rippleFill]. + */ + fun setRippleFill(rippleFill: Boolean) { + rippleShader.rippleFill = rippleFill + } + override fun onDraw(canvas: Canvas?) { if (canvas == null || !canvas.isHardwareAccelerated) { // Drawing with the ripple shader requires hardware acceleration, so skip @@ -107,6 +118,6 @@ class ChargingRippleView(context: Context?, attrs: AttributeSet?) : View(context // animation implementation in the ripple shader. val maskRadius = (1 - (1 - rippleShader.progress) * (1 - rippleShader.progress) * (1 - rippleShader.progress)) * radius * 2 - canvas?.drawCircle(origin.x, origin.y, maskRadius, ripplePaint) + canvas.drawCircle(origin.x, origin.y, maskRadius, ripplePaint) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java index abca9b024445..ee79a4d908c2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java @@ -64,6 +64,7 @@ import com.android.internal.os.SomeArgs; import com.android.internal.statusbar.IAddTileResultCallback; import com.android.internal.statusbar.IStatusBar; import com.android.internal.statusbar.IUndoMediaTransferCallback; +import com.android.internal.statusbar.LetterboxDetails; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.util.GcUtils; import com.android.internal.view.AppearanceRegion; @@ -359,7 +360,7 @@ public class CommandQueue extends IStatusBar.Stub implements default void onSystemBarAttributesChanged(int displayId, @Appearance int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, @Behavior int behavior, InsetsVisibilities requestedVisibilities, - String packageName) { } + String packageName, LetterboxDetails[] letterboxDetails) { } /** * @see IStatusBar#showTransient(int, int[], boolean). @@ -1087,7 +1088,8 @@ public class CommandQueue extends IStatusBar.Stub implements @Override public void onSystemBarAttributesChanged(int displayId, @Appearance int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, - @Behavior int behavior, InsetsVisibilities requestedVisibilities, String packageName) { + @Behavior int behavior, InsetsVisibilities requestedVisibilities, String packageName, + LetterboxDetails[] letterboxDetails) { synchronized (mLock) { SomeArgs args = SomeArgs.obtain(); args.argi1 = displayId; @@ -1097,6 +1099,7 @@ public class CommandQueue extends IStatusBar.Stub implements args.argi4 = behavior; args.arg2 = requestedVisibilities; args.arg3 = packageName; + args.arg4 = letterboxDetails; mHandler.obtainMessage(MSG_SYSTEM_BAR_CHANGED, args).sendToTarget(); } } @@ -1558,7 +1561,8 @@ public class CommandQueue extends IStatusBar.Stub implements for (int i = 0; i < mCallbacks.size(); i++) { mCallbacks.get(i).onSystemBarAttributesChanged(args.argi1, args.argi2, (AppearanceRegion[]) args.arg1, args.argi3 == 1, args.argi4, - (InsetsVisibilities) args.arg2, (String) args.arg3); + (InsetsVisibilities) args.arg2, (String) args.arg3, + (LetterboxDetails[]) args.arg4); } args.recycle(); break; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt index 5aeab84b677c..d24896148095 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt @@ -31,7 +31,6 @@ import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.collection.inflation.BindEventManager -import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow @@ -129,11 +128,9 @@ class AnimatedImageNotificationManager @Inject constructor( */ @SysUISingleton class ConversationNotificationManager @Inject constructor( - private val bindEventManager: BindEventManager, - private val notificationGroupManager: NotificationGroupManagerLegacy, + bindEventManager: BindEventManager, private val context: Context, private val notifCollection: CommonNotifCollection, - private val featureFlags: NotifPipelineFlags, @Main private val mainHandler: Handler ) { // Need this state to be thread safe, since it's accessed from the ui thread @@ -172,12 +169,10 @@ class ConversationNotificationManager @Inject constructor( layout.setIsImportantConversation(important, false) } } - if (changed && !featureFlags.isNewPipelineEnabled()) { - notificationGroupManager.updateIsolation(entry) - } } } } + fun onEntryViewBound(entry: NotificationEntry) { if (!entry.ranking.isConversation) { return diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java index c9c7fe9e0ab6..27a7cd779405 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java @@ -226,10 +226,8 @@ public interface NotificationsModule { static NotificationLogger provideNotificationLogger( NotificationListener notificationListener, @UiBackground Executor uiBgExecutor, - NotifPipelineFlags notifPipelineFlags, NotifLiveDataStore notifLiveDataStore, NotificationVisibilityProvider visibilityProvider, - NotificationEntryManager entryManager, NotifPipeline notifPipeline, StatusBarStateController statusBarStateController, NotificationLogger.ExpansionStateLogger expansionStateLogger, @@ -237,10 +235,8 @@ public interface NotificationsModule { return new NotificationLogger( notificationListener, uiBgExecutor, - notifPipelineFlags, notifLiveDataStore, visibilityProvider, - entryManager, notifPipeline, statusBarStateController, expansionStateLogger, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java index 8378b69bee9a..2dd95a3cbab8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java @@ -294,11 +294,6 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter * @return true if these checks pass, false if the notification should not alert */ private boolean canAlertCommon(NotificationEntry entry) { - if (!mFlags.isNewPipelineEnabled() && mNotificationFilter.shouldFilterOut(entry)) { - mLogger.logNoAlertingFilteredOut(entry); - return false; - } - for (int i = 0; i < mSuppressors.size(); i++) { if (mSuppressors.get(i).suppressInterruptions(entry)) { mLogger.logNoAlertingSuppressedBy(entry, mSuppressors.get(i), /* awake */ false); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java index 9fbd5c39dedd..639187790ae0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java @@ -22,7 +22,6 @@ import android.os.ServiceManager; import android.os.SystemClock; import android.os.Trace; import android.service.notification.NotificationListenerService; -import android.service.notification.StatusBarNotification; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; @@ -39,9 +38,6 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.notification.NotifPipelineFlags; -import com.android.systemui.statusbar.notification.NotificationEntryListener; -import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotifLiveDataStore; import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.NotificationEntry; @@ -80,7 +76,6 @@ public class NotificationLogger implements StateListener { private final Executor mUiBgExecutor; private final NotifLiveDataStore mNotifLiveDataStore; private final NotificationVisibilityProvider mVisibilityProvider; - private final NotificationEntryManager mEntryManager; private final NotifPipeline mNotifPipeline; private final NotificationPanelLogger mNotificationPanelLogger; private final ExpansionStateLogger mExpansionStateLogger; @@ -220,10 +215,8 @@ public class NotificationLogger implements StateListener { */ public NotificationLogger(NotificationListener notificationListener, @UiBackground Executor uiBgExecutor, - NotifPipelineFlags notifPipelineFlags, NotifLiveDataStore notifLiveDataStore, NotificationVisibilityProvider visibilityProvider, - NotificationEntryManager entryManager, NotifPipeline notifPipeline, StatusBarStateController statusBarStateController, ExpansionStateLogger expansionStateLogger, @@ -232,7 +225,6 @@ public class NotificationLogger implements StateListener { mUiBgExecutor = uiBgExecutor; mNotifLiveDataStore = notifLiveDataStore; mVisibilityProvider = visibilityProvider; - mEntryManager = entryManager; mNotifPipeline = notifPipeline; mBarService = IStatusBarService.Stub.asInterface( ServiceManager.getService(Context.STATUS_BAR_SERVICE)); @@ -241,36 +233,7 @@ public class NotificationLogger implements StateListener { // Not expected to be destroyed, don't need to unsubscribe statusBarStateController.addCallback(this); - if (notifPipelineFlags.isNewPipelineEnabled()) { - registerNewPipelineListener(); - } else { - registerLegacyListener(); - } - } - - private void registerLegacyListener() { - mEntryManager.addNotificationEntryListener(new NotificationEntryListener() { - @Override - public void onEntryRemoved( - NotificationEntry entry, - NotificationVisibility visibility, - boolean removedByUser, - int reason) { - mExpansionStateLogger.onEntryRemoved(entry.getKey()); - } - - @Override - public void onPreEntryUpdated(NotificationEntry entry) { - mExpansionStateLogger.onEntryUpdated(entry.getKey()); - } - - @Override - public void onInflationError( - StatusBarNotification notification, - Exception exception) { - logNotificationError(notification, exception); - } - }); + registerNewPipelineListener(); } private void registerNewPipelineListener() { @@ -333,26 +296,6 @@ public class NotificationLogger implements StateListener { } } - /** - * Logs Notification inflation error - */ - private void logNotificationError( - StatusBarNotification notification, - Exception exception) { - try { - mBarService.onNotificationError( - notification.getPackageName(), - notification.getTag(), - notification.getId(), - notification.getUid(), - notification.getInitialPid(), - exception.getMessage(), - notification.getUserId()); - } catch (RemoteException ex) { - // The end is nigh. - } - } - private void logNotificationVisibilityChanges( Collection<NotificationVisibility> newlyVisible, Collection<NotificationVisibility> noLongerVisible) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java index 4013254c6592..6d513d0da5c1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java @@ -24,8 +24,7 @@ import android.util.MathUtils; import android.view.View; import android.view.ViewGroup; -import androidx.annotation.VisibleForTesting; - +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.policy.SystemBarUtils; import com.android.keyguard.BouncerPanelExpansionCalculator; import com.android.systemui.R; @@ -65,6 +64,9 @@ public class StackScrollAlgorithm { private int mPinnedZTranslationExtra; private float mNotificationScrimPadding; private int mMarginBottom; + private float mQuickQsOffsetHeight; + private float mSmallCornerRadius; + private float mLargeCornerRadius; public StackScrollAlgorithm( Context context, @@ -74,10 +76,10 @@ public class StackScrollAlgorithm { } public void initView(Context context) { - initConstants(context); + updateResources(context); } - private void initConstants(Context context) { + private void updateResources(Context context) { Resources res = context.getResources(); mPaddingBetweenElements = res.getDimensionPixelSize( R.dimen.notification_divider_height); @@ -93,6 +95,9 @@ public class StackScrollAlgorithm { R.dimen.notification_section_divider_height_lockscreen); mNotificationScrimPadding = res.getDimensionPixelSize(R.dimen.notification_side_paddings); mMarginBottom = res.getDimensionPixelSize(R.dimen.notification_panel_margin_bottom); + mQuickQsOffsetHeight = SystemBarUtils.getQuickQsOffsetHeight(context); + mSmallCornerRadius = res.getDimension(R.dimen.notification_corner_radius_small); + mLargeCornerRadius = res.getDimension(R.dimen.notification_corner_radius); } /** @@ -441,6 +446,15 @@ public class StackScrollAlgorithm { return false; } + @VisibleForTesting + void maybeUpdateHeadsUpIsVisible(ExpandableViewState viewState, boolean isShadeExpanded, + boolean mustStayOnScreen, boolean topVisible, float viewEnd, float hunMax) { + + if (isShadeExpanded && mustStayOnScreen && topVisible) { + viewState.headsUpIsVisible = viewEnd < hunMax; + } + } + // TODO(b/172289889) polish shade open from HUN /** * Populates the {@link ExpandableViewState} for a single child. @@ -474,14 +488,6 @@ public class StackScrollAlgorithm { : ShadeInterpolation.getContentAlpha(expansion); } - if (ambientState.isShadeExpanded() && view.mustStayOnScreen() - && viewState.yTranslation >= 0) { - // Even if we're not scrolled away we're in view and we're also not in the - // shelf. We can relax the constraints and let us scroll off the top! - float end = viewState.yTranslation + viewState.height + ambientState.getStackY(); - viewState.headsUpIsVisible = end < ambientState.getMaxHeadsUpTranslation(); - } - final float expansionFraction = getExpansionFractionWithoutShelf( algorithmState, ambientState); @@ -497,8 +503,15 @@ public class StackScrollAlgorithm { algorithmState.mCurrentExpandedYPosition += gap; } + // Must set viewState.yTranslation _before_ use. + // Incoming views have yTranslation=0 by default. viewState.yTranslation = algorithmState.mCurrentYPosition; + maybeUpdateHeadsUpIsVisible(viewState, ambientState.isShadeExpanded(), + view.mustStayOnScreen(), /* topVisible */ viewState.yTranslation >= 0, + /* viewEnd */ viewState.yTranslation + viewState.height + ambientState.getStackY(), + /* hunMax */ ambientState.getMaxHeadsUpTranslation() + ); if (view instanceof FooterView) { final boolean shadeClosed = !ambientState.isShadeExpanded(); final boolean isShelfShowing = algorithmState.firstViewInShelf != null; @@ -682,7 +695,8 @@ public class StackScrollAlgorithm { if (row.mustStayOnScreen() && !childState.headsUpIsVisible && !row.showingPulsing()) { // Ensure that the heads up is always visible even when scrolled off - clampHunToTop(ambientState, row, childState); + clampHunToTop(mQuickQsOffsetHeight, ambientState.getStackTranslation(), + row.getCollapsedHeight(), childState); if (isTopEntry && row.isAboveShelf()) { // the first hun can't get off screen. clampHunToMaxTranslation(ambientState, row, childState); @@ -719,27 +733,62 @@ public class StackScrollAlgorithm { } } - private void clampHunToTop(AmbientState ambientState, ExpandableNotificationRow row, - ExpandableViewState childState) { - float newTranslation = Math.max(ambientState.getTopPadding() - + ambientState.getStackTranslation(), childState.yTranslation); - childState.height = (int) Math.max(childState.height - (newTranslation - - childState.yTranslation), row.getCollapsedHeight()); - childState.yTranslation = newTranslation; + /** + * When shade is open and we are scrolled to the bottom of notifications, + * clamp incoming HUN in its collapsed form, right below qs offset. + * Transition pinned collapsed HUN to full height when scrolling back up. + */ + @VisibleForTesting + void clampHunToTop(float quickQsOffsetHeight, float stackTranslation, float collapsedHeight, + ExpandableViewState viewState) { + + final float newTranslation = Math.max(quickQsOffsetHeight + stackTranslation, + viewState.yTranslation); + + // Transition from collapsed pinned state to fully expanded state + // when the pinned HUN approaches its actual location (when scrolling back to top). + final float distToRealY = newTranslation - viewState.yTranslation; + viewState.height = (int) Math.max(viewState.height - distToRealY, collapsedHeight); + viewState.yTranslation = newTranslation; } + // Pin HUN to bottom of expanded QS + // while the rest of notifications are scrolled offscreen. private void clampHunToMaxTranslation(AmbientState ambientState, ExpandableNotificationRow row, ExpandableViewState childState) { - float newTranslation; float maxHeadsUpTranslation = ambientState.getMaxHeadsUpTranslation(); - float maxShelfPosition = ambientState.getInnerHeight() + ambientState.getTopPadding() + final float maxShelfPosition = ambientState.getInnerHeight() + ambientState.getTopPadding() + ambientState.getStackTranslation(); maxHeadsUpTranslation = Math.min(maxHeadsUpTranslation, maxShelfPosition); - float bottomPosition = maxHeadsUpTranslation - row.getCollapsedHeight(); - newTranslation = Math.min(childState.yTranslation, bottomPosition); + + final float bottomPosition = maxHeadsUpTranslation - row.getCollapsedHeight(); + final float newTranslation = Math.min(childState.yTranslation, bottomPosition); childState.height = (int) Math.min(childState.height, maxHeadsUpTranslation - newTranslation); childState.yTranslation = newTranslation; + + // Animate pinned HUN bottom corners to and from original roundness. + final float originalCornerRadius = + row.isLastInSection() ? 1f : (mSmallCornerRadius / mLargeCornerRadius); + final float roundness = computeCornerRoundnessForPinnedHun(mHostView.getHeight(), + ambientState.getStackY(), getMaxAllowedChildHeight(row), originalCornerRadius); + row.setBottomRoundness(roundness, /* animate= */ false); + } + + @VisibleForTesting + float computeCornerRoundnessForPinnedHun(float hostViewHeight, float stackY, + float viewMaxHeight, float originalCornerRadius) { + + // Compute y where corner roundness should be in its original unpinned state. + // We use view max height because the pinned collapsed HUN expands to max height + // when it becomes unpinned. + final float originalRoundnessY = hostViewHeight - viewMaxHeight; + + final float distToOriginalRoundness = Math.max(0f, stackY - originalRoundnessY); + final float progressToPinnedRoundness = Math.min(1f, + distToOriginalRoundness / viewMaxHeight); + + return MathUtils.lerp(originalCornerRadius, 1f, progressToPinnedRoundness); } protected int getMaxAllowedChildHeight(View child) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java index 39620ac23117..a0f386ff0b5e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java @@ -448,7 +448,6 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp } // During wake and unlock, we need to draw black before waking up to avoid abrupt // brightness changes due to display state transitions. - boolean alwaysOnEnabled = mDozeParameters.getAlwaysOn(); Runnable wakeUp = ()-> { if (!wasDeviceInteractive) { if (DEBUG_BIO_WAKELOCK) { @@ -659,7 +658,10 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp mLatencyTracker.onActionCancel(action); } - if (biometricSourceType == BiometricSourceType.FINGERPRINT + if (!mVibratorHelper.hasVibrator() + && (!mUpdateMonitor.isDeviceInteractive() || mUpdateMonitor.isDreaming())) { + startWakeAndUnlock(MODE_SHOW_BOUNCER); + } else if (biometricSourceType == BiometricSourceType.FINGERPRINT && mUpdateMonitor.isUdfpsSupported()) { long currUptimeMillis = SystemClock.uptimeMillis(); if (currUptimeMillis - mLastFpFailureUptimeMillis < mConsecutiveFpFailureThreshold) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java index 28356730dab1..b7a605a793bb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java @@ -427,12 +427,6 @@ public interface CentralSurfaces extends Dumpable, ActivityStarter, LifecycleOwn void onHintFinished(); - void onCameraHintStarted(); - - void onVoiceAssistHintStarted(); - - void onPhoneHintStarted(); - void onTrackingStopped(boolean expand); // TODO: Figure out way to remove these. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java index 9060d5f67913..cb9afe887ab7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java @@ -45,6 +45,7 @@ import android.view.WindowInsetsController.Behavior; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.internal.statusbar.LetterboxDetails; import com.android.internal.view.AppearanceRegion; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.R; @@ -388,8 +389,7 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba if (mStatusBarKeyguardViewManager.isBouncerShowing()) { mStatusBarKeyguardViewManager.reset(true /* hide */); } - mNotificationPanelViewController.launchCamera( - mCentralSurfaces.isDeviceInteractive() /* animate */, source); + mNotificationPanelViewController.launchCamera(source); mCentralSurfaces.updateScrimController(); } else { // We need to defer the camera launch until the screen comes on, since otherwise @@ -464,7 +464,8 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba @Override public void onSystemBarAttributesChanged(int displayId, @Appearance int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, - @Behavior int behavior, InsetsVisibilities requestedVisibilities, String packageName) { + @Behavior int behavior, InsetsVisibilities requestedVisibilities, String packageName, + LetterboxDetails[] letterboxDetails) { if (displayId != mDisplayId) { return; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java index 4ca14598dd36..f627c5bb9d02 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java @@ -138,6 +138,7 @@ import com.android.systemui.assist.AssistManager; import com.android.systemui.biometrics.AuthRippleController; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.camera.CameraIntents; +import com.android.systemui.charging.WiredChargingRippleController; import com.android.systemui.charging.WirelessChargingAnimation; import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.colorextraction.SysuiColorExtractor; @@ -196,7 +197,6 @@ import com.android.systemui.statusbar.PowerButtonReveal; import com.android.systemui.statusbar.PulseExpansionHandler; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.SysuiStatusBarStateController; -import com.android.systemui.statusbar.charging.WiredChargingRippleController; import com.android.systemui.statusbar.connectivity.NetworkController; import com.android.systemui.statusbar.core.StatusBarInitializer; import com.android.systemui.statusbar.notification.DynamicPrivacyController; @@ -958,7 +958,7 @@ public class CentralSurfacesImpl extends CoreStartable implements } mCommandQueueCallbacks.onSystemBarAttributesChanged(mDisplayId, result.mAppearance, result.mAppearanceRegions, result.mNavbarColorManagedByIme, result.mBehavior, - result.mRequestedVisibilities, result.mPackageName); + result.mRequestedVisibilities, result.mPackageName, result.mLetterboxDetails); // StatusBarManagerService has a back up of IME token and it's restored here. mCommandQueueCallbacks.setImeWindowStatus(mDisplayId, result.mImeToken, @@ -1268,8 +1268,6 @@ public class CentralSurfacesImpl extends CoreStartable implements backdrop.setScaleY(scale); }); - mNotificationPanelViewController.setUserSetupComplete(mUserSetup); - // Set up the quick settings tile panel final View container = mNotificationShadeWindowView.findViewById(R.id.qs_frame); if (container != null) { @@ -1744,6 +1742,7 @@ public class CentralSurfacesImpl extends CoreStartable implements // activity is exited. if (mKeyguardStateController.isShowing() && !mKeyguardStateController.isKeyguardGoingAway()) { + Log.d(TAG, "Setting occluded = true in #startActivity."); mKeyguardViewMediator.setOccluded(true /* isOccluded */, true /* animate */); } @@ -3007,8 +3006,7 @@ public class CentralSurfacesImpl extends CoreStartable implements @Override public boolean isInLaunchTransition() { - return mNotificationPanelViewController.isLaunchTransitionRunning() - || mNotificationPanelViewController.isLaunchTransitionFinished(); + return mNotificationPanelViewController.isLaunchTransitionFinished(); } /** @@ -3040,11 +3038,7 @@ public class CentralSurfacesImpl extends CoreStartable implements mCommandQueue.appTransitionStarting(mDisplayId, SystemClock.uptimeMillis(), LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION, true); }; - if (mNotificationPanelViewController.isLaunchTransitionRunning()) { - mNotificationPanelViewController.setLaunchTransitionEndRunnable(hideRunnable); - } else { - hideRunnable.run(); - } + hideRunnable.run(); } private void cancelAfterLaunchTransitionRunnables() { @@ -3053,7 +3047,6 @@ public class CentralSurfacesImpl extends CoreStartable implements } mLaunchTransitionEndRunnable = null; mLaunchTransitionCancelRunnable = null; - mNotificationPanelViewController.setLaunchTransitionEndRunnable(null); } /** @@ -3482,24 +3475,6 @@ public class CentralSurfacesImpl extends CoreStartable implements } @Override - public void onCameraHintStarted() { - mFalsingCollector.onCameraHintStarted(); - mKeyguardIndicationController.showTransientIndication(R.string.camera_hint); - } - - @Override - public void onVoiceAssistHintStarted() { - mFalsingCollector.onLeftAffordanceHintStarted(); - mKeyguardIndicationController.showTransientIndication(R.string.voice_hint); - } - - @Override - public void onPhoneHintStarted() { - mFalsingCollector.onLeftAffordanceHintStarted(); - mKeyguardIndicationController.showTransientIndication(R.string.phone_hint); - } - - @Override public void onTrackingStopped(boolean expand) { } @@ -3683,8 +3658,7 @@ public class CentralSurfacesImpl extends CoreStartable implements mWakeUpCoordinator.setFullyAwake(true); mWakeUpCoordinator.setWakingUp(false); if (mLaunchCameraWhenFinishedWaking) { - mNotificationPanelViewController.launchCamera( - false /* animate */, mLastCameraLaunchSource); + mNotificationPanelViewController.launchCamera(mLastCameraLaunchSource); mLaunchCameraWhenFinishedWaking = false; } if (mLaunchEmergencyActionWhenFinishedWaking) { @@ -4326,9 +4300,6 @@ public class CentralSurfacesImpl extends CoreStartable implements if (!mUserSetup) { animateCollapseQuickSettings(); } - if (mNotificationPanelViewController != null) { - mNotificationPanelViewController.setUserSetupComplete(mUserSetup); - } updateQsExpansionEnabled(); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java deleted file mode 100644 index 2922b4c98d34..000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java +++ /dev/null @@ -1,587 +0,0 @@ -/* - * Copyright (C) 2014 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.statusbar.phone; - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ValueAnimator; -import android.content.Context; -import android.view.MotionEvent; -import android.view.VelocityTracker; -import android.view.View; -import android.view.ViewConfiguration; - -import com.android.systemui.R; -import com.android.systemui.animation.Interpolators; -import com.android.systemui.classifier.Classifier; -import com.android.systemui.plugins.FalsingManager; -import com.android.systemui.statusbar.KeyguardAffordanceView; -import com.android.wm.shell.animation.FlingAnimationUtils; - -/** - * A touch handler of the keyguard which is responsible for launching phone and camera affordances. - */ -public class KeyguardAffordanceHelper { - - public static final long HINT_PHASE1_DURATION = 200; - private static final long HINT_PHASE2_DURATION = 350; - private static final float BACKGROUND_RADIUS_SCALE_FACTOR = 0.25f; - private static final int HINT_CIRCLE_OPEN_DURATION = 500; - - private final Context mContext; - private final Callback mCallback; - - private FlingAnimationUtils mFlingAnimationUtils; - private VelocityTracker mVelocityTracker; - private boolean mSwipingInProgress; - private float mInitialTouchX; - private float mInitialTouchY; - private float mTranslation; - private float mTranslationOnDown; - private int mTouchSlop; - private int mMinTranslationAmount; - private int mMinFlingVelocity; - private int mHintGrowAmount; - private KeyguardAffordanceView mLeftIcon; - private KeyguardAffordanceView mRightIcon; - private Animator mSwipeAnimator; - private final FalsingManager mFalsingManager; - private int mMinBackgroundRadius; - private boolean mMotionCancelled; - private int mTouchTargetSize; - private View mTargetedView; - private boolean mTouchSlopExeeded; - private AnimatorListenerAdapter mFlingEndListener = new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mSwipeAnimator = null; - mSwipingInProgress = false; - mTargetedView = null; - } - }; - private Runnable mAnimationEndRunnable = new Runnable() { - @Override - public void run() { - mCallback.onAnimationToSideEnded(); - } - }; - - KeyguardAffordanceHelper(Callback callback, Context context, FalsingManager falsingManager) { - mContext = context; - mCallback = callback; - initIcons(); - updateIcon(mLeftIcon, 0.0f, mLeftIcon.getRestingAlpha(), false, false, true, false); - updateIcon(mRightIcon, 0.0f, mRightIcon.getRestingAlpha(), false, false, true, false); - mFalsingManager = falsingManager; - initDimens(); - } - - private void initDimens() { - final ViewConfiguration configuration = ViewConfiguration.get(mContext); - mTouchSlop = configuration.getScaledPagingTouchSlop(); - mMinFlingVelocity = configuration.getScaledMinimumFlingVelocity(); - mMinTranslationAmount = mContext.getResources().getDimensionPixelSize( - R.dimen.keyguard_min_swipe_amount); - mMinBackgroundRadius = mContext.getResources().getDimensionPixelSize( - R.dimen.keyguard_affordance_min_background_radius); - mTouchTargetSize = mContext.getResources().getDimensionPixelSize( - R.dimen.keyguard_affordance_touch_target_size); - mHintGrowAmount = - mContext.getResources().getDimensionPixelSize(R.dimen.hint_grow_amount_sideways); - mFlingAnimationUtils = new FlingAnimationUtils(mContext.getResources().getDisplayMetrics(), - 0.4f); - } - - private void initIcons() { - mLeftIcon = mCallback.getLeftIcon(); - mRightIcon = mCallback.getRightIcon(); - updatePreviews(); - } - - public void updatePreviews() { - mLeftIcon.setPreviewView(mCallback.getLeftPreview()); - mRightIcon.setPreviewView(mCallback.getRightPreview()); - } - - public boolean onTouchEvent(MotionEvent event) { - int action = event.getActionMasked(); - if (mMotionCancelled && action != MotionEvent.ACTION_DOWN) { - return false; - } - final float y = event.getY(); - final float x = event.getX(); - - boolean isUp = false; - switch (action) { - case MotionEvent.ACTION_DOWN: - View targetView = getIconAtPosition(x, y); - if (targetView == null || (mTargetedView != null && mTargetedView != targetView)) { - mMotionCancelled = true; - return false; - } - if (mTargetedView != null) { - cancelAnimation(); - } else { - mTouchSlopExeeded = false; - } - startSwiping(targetView); - mInitialTouchX = x; - mInitialTouchY = y; - mTranslationOnDown = mTranslation; - initVelocityTracker(); - trackMovement(event); - mMotionCancelled = false; - break; - case MotionEvent.ACTION_POINTER_DOWN: - mMotionCancelled = true; - endMotion(true /* forceSnapBack */, x, y); - break; - case MotionEvent.ACTION_MOVE: - trackMovement(event); - float xDist = x - mInitialTouchX; - float yDist = y - mInitialTouchY; - float distance = (float) Math.hypot(xDist, yDist); - if (!mTouchSlopExeeded && distance > mTouchSlop) { - mTouchSlopExeeded = true; - } - if (mSwipingInProgress) { - if (mTargetedView == mRightIcon) { - distance = mTranslationOnDown - distance; - distance = Math.min(0, distance); - } else { - distance = mTranslationOnDown + distance; - distance = Math.max(0, distance); - } - setTranslation(distance, false /* isReset */, false /* animateReset */); - } - break; - - case MotionEvent.ACTION_UP: - isUp = true; - case MotionEvent.ACTION_CANCEL: - boolean hintOnTheRight = mTargetedView == mRightIcon; - trackMovement(event); - endMotion(!isUp, x, y); - if (!mTouchSlopExeeded && isUp) { - mCallback.onIconClicked(hintOnTheRight); - } - break; - } - return true; - } - - private void startSwiping(View targetView) { - mCallback.onSwipingStarted(targetView == mRightIcon); - mSwipingInProgress = true; - mTargetedView = targetView; - } - - private View getIconAtPosition(float x, float y) { - if (leftSwipePossible() && isOnIcon(mLeftIcon, x, y)) { - return mLeftIcon; - } - if (rightSwipePossible() && isOnIcon(mRightIcon, x, y)) { - return mRightIcon; - } - return null; - } - - public boolean isOnAffordanceIcon(float x, float y) { - return isOnIcon(mLeftIcon, x, y) || isOnIcon(mRightIcon, x, y); - } - - private boolean isOnIcon(View icon, float x, float y) { - float iconX = icon.getX() + icon.getWidth() / 2.0f; - float iconY = icon.getY() + icon.getHeight() / 2.0f; - double distance = Math.hypot(x - iconX, y - iconY); - return distance <= mTouchTargetSize / 2; - } - - private void endMotion(boolean forceSnapBack, float lastX, float lastY) { - if (mSwipingInProgress) { - flingWithCurrentVelocity(forceSnapBack, lastX, lastY); - } else { - mTargetedView = null; - } - if (mVelocityTracker != null) { - mVelocityTracker.recycle(); - mVelocityTracker = null; - } - } - - private boolean rightSwipePossible() { - return mRightIcon.getVisibility() == View.VISIBLE; - } - - private boolean leftSwipePossible() { - return mLeftIcon.getVisibility() == View.VISIBLE; - } - - public boolean onInterceptTouchEvent(MotionEvent ev) { - return false; - } - - public void startHintAnimation(boolean right, - Runnable onFinishedListener) { - cancelAnimation(); - startHintAnimationPhase1(right, onFinishedListener); - } - - private void startHintAnimationPhase1(final boolean right, final Runnable onFinishedListener) { - final KeyguardAffordanceView targetView = right ? mRightIcon : mLeftIcon; - ValueAnimator animator = getAnimatorToRadius(right, mHintGrowAmount); - animator.addListener(new AnimatorListenerAdapter() { - private boolean mCancelled; - - @Override - public void onAnimationCancel(Animator animation) { - mCancelled = true; - } - - @Override - public void onAnimationEnd(Animator animation) { - if (mCancelled) { - mSwipeAnimator = null; - mTargetedView = null; - onFinishedListener.run(); - } else { - startUnlockHintAnimationPhase2(right, onFinishedListener); - } - } - }); - animator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN); - animator.setDuration(HINT_PHASE1_DURATION); - animator.start(); - mSwipeAnimator = animator; - mTargetedView = targetView; - } - - /** - * Phase 2: Move back. - */ - private void startUnlockHintAnimationPhase2(boolean right, final Runnable onFinishedListener) { - ValueAnimator animator = getAnimatorToRadius(right, 0); - animator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mSwipeAnimator = null; - mTargetedView = null; - onFinishedListener.run(); - } - }); - animator.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN); - animator.setDuration(HINT_PHASE2_DURATION); - animator.setStartDelay(HINT_CIRCLE_OPEN_DURATION); - animator.start(); - mSwipeAnimator = animator; - } - - private ValueAnimator getAnimatorToRadius(final boolean right, int radius) { - final KeyguardAffordanceView targetView = right ? mRightIcon : mLeftIcon; - ValueAnimator animator = ValueAnimator.ofFloat(targetView.getCircleRadius(), radius); - animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - float newRadius = (float) animation.getAnimatedValue(); - targetView.setCircleRadiusWithoutAnimation(newRadius); - float translation = getTranslationFromRadius(newRadius); - mTranslation = right ? -translation : translation; - updateIconsFromTranslation(targetView); - } - }); - return animator; - } - - private void cancelAnimation() { - if (mSwipeAnimator != null) { - mSwipeAnimator.cancel(); - } - } - - private void flingWithCurrentVelocity(boolean forceSnapBack, float lastX, float lastY) { - float vel = getCurrentVelocity(lastX, lastY); - - // We snap back if the current translation is not far enough - boolean snapBack = false; - if (mCallback.needsAntiFalsing()) { - snapBack = snapBack || mFalsingManager.isFalseTouch( - mTargetedView == mRightIcon - ? Classifier.RIGHT_AFFORDANCE : Classifier.LEFT_AFFORDANCE); - } - snapBack = snapBack || isBelowFalsingThreshold(); - - // or if the velocity is in the opposite direction. - boolean velIsInWrongDirection = vel * mTranslation < 0; - snapBack |= Math.abs(vel) > mMinFlingVelocity && velIsInWrongDirection; - vel = snapBack ^ velIsInWrongDirection ? 0 : vel; - fling(vel, snapBack || forceSnapBack, mTranslation < 0); - } - - private boolean isBelowFalsingThreshold() { - return Math.abs(mTranslation) < Math.abs(mTranslationOnDown) + getMinTranslationAmount(); - } - - private int getMinTranslationAmount() { - float factor = mCallback.getAffordanceFalsingFactor(); - return (int) (mMinTranslationAmount * factor); - } - - private void fling(float vel, final boolean snapBack, boolean right) { - float target = right ? -mCallback.getMaxTranslationDistance() - : mCallback.getMaxTranslationDistance(); - target = snapBack ? 0 : target; - - ValueAnimator animator = ValueAnimator.ofFloat(mTranslation, target); - mFlingAnimationUtils.apply(animator, mTranslation, target, vel); - animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - mTranslation = (float) animation.getAnimatedValue(); - } - }); - animator.addListener(mFlingEndListener); - if (!snapBack) { - startFinishingCircleAnimation(vel * 0.375f, mAnimationEndRunnable, right); - mCallback.onAnimationToSideStarted(right, mTranslation, vel); - } else { - reset(true); - } - animator.start(); - mSwipeAnimator = animator; - if (snapBack) { - mCallback.onSwipingAborted(); - } - } - - private void startFinishingCircleAnimation(float velocity, Runnable animationEndRunnable, - boolean right) { - KeyguardAffordanceView targetView = right ? mRightIcon : mLeftIcon; - targetView.finishAnimation(velocity, animationEndRunnable); - } - - private void setTranslation(float translation, boolean isReset, boolean animateReset) { - translation = rightSwipePossible() ? translation : Math.max(0, translation); - translation = leftSwipePossible() ? translation : Math.min(0, translation); - float absTranslation = Math.abs(translation); - if (translation != mTranslation || isReset) { - KeyguardAffordanceView targetView = translation > 0 ? mLeftIcon : mRightIcon; - KeyguardAffordanceView otherView = translation > 0 ? mRightIcon : mLeftIcon; - float alpha = absTranslation / getMinTranslationAmount(); - - // We interpolate the alpha of the other icons to 0 - float fadeOutAlpha = 1.0f - alpha; - fadeOutAlpha = Math.max(fadeOutAlpha, 0.0f); - - boolean animateIcons = isReset && animateReset; - boolean forceNoCircleAnimation = isReset && !animateReset; - float radius = getRadiusFromTranslation(absTranslation); - boolean slowAnimation = isReset && isBelowFalsingThreshold(); - if (!isReset) { - updateIcon(targetView, radius, alpha + fadeOutAlpha * targetView.getRestingAlpha(), - false, false, false, false); - } else { - updateIcon(targetView, 0.0f, fadeOutAlpha * targetView.getRestingAlpha(), - animateIcons, slowAnimation, true /* isReset */, forceNoCircleAnimation); - } - updateIcon(otherView, 0.0f, fadeOutAlpha * otherView.getRestingAlpha(), - animateIcons, slowAnimation, isReset, forceNoCircleAnimation); - - mTranslation = translation; - } - } - - private void updateIconsFromTranslation(KeyguardAffordanceView targetView) { - float absTranslation = Math.abs(mTranslation); - float alpha = absTranslation / getMinTranslationAmount(); - - // We interpolate the alpha of the other icons to 0 - float fadeOutAlpha = 1.0f - alpha; - fadeOutAlpha = Math.max(0.0f, fadeOutAlpha); - - // We interpolate the alpha of the targetView to 1 - KeyguardAffordanceView otherView = targetView == mRightIcon ? mLeftIcon : mRightIcon; - updateIconAlpha(targetView, alpha + fadeOutAlpha * targetView.getRestingAlpha(), false); - updateIconAlpha(otherView, fadeOutAlpha * otherView.getRestingAlpha(), false); - } - - private float getTranslationFromRadius(float circleSize) { - float translation = (circleSize - mMinBackgroundRadius) - / BACKGROUND_RADIUS_SCALE_FACTOR; - return translation > 0.0f ? translation + mTouchSlop : 0.0f; - } - - private float getRadiusFromTranslation(float translation) { - if (translation <= mTouchSlop) { - return 0.0f; - } - return (translation - mTouchSlop) * BACKGROUND_RADIUS_SCALE_FACTOR + mMinBackgroundRadius; - } - - public void animateHideLeftRightIcon() { - cancelAnimation(); - updateIcon(mRightIcon, 0f, 0f, true, false, false, false); - updateIcon(mLeftIcon, 0f, 0f, true, false, false, false); - } - - private void updateIcon(KeyguardAffordanceView view, float circleRadius, float alpha, - boolean animate, boolean slowRadiusAnimation, boolean force, - boolean forceNoCircleAnimation) { - if (view.getVisibility() != View.VISIBLE && !force) { - return; - } - if (forceNoCircleAnimation) { - view.setCircleRadiusWithoutAnimation(circleRadius); - } else { - view.setCircleRadius(circleRadius, slowRadiusAnimation); - } - updateIconAlpha(view, alpha, animate); - } - - private void updateIconAlpha(KeyguardAffordanceView view, float alpha, boolean animate) { - float scale = getScale(alpha, view); - alpha = Math.min(1.0f, alpha); - view.setImageAlpha(alpha, animate); - view.setImageScale(scale, animate); - } - - private float getScale(float alpha, KeyguardAffordanceView icon) { - float scale = alpha / icon.getRestingAlpha() * 0.2f + - KeyguardAffordanceView.MIN_ICON_SCALE_AMOUNT; - return Math.min(scale, KeyguardAffordanceView.MAX_ICON_SCALE_AMOUNT); - } - - private void trackMovement(MotionEvent event) { - if (mVelocityTracker != null) { - mVelocityTracker.addMovement(event); - } - } - - private void initVelocityTracker() { - if (mVelocityTracker != null) { - mVelocityTracker.recycle(); - } - mVelocityTracker = VelocityTracker.obtain(); - } - - private float getCurrentVelocity(float lastX, float lastY) { - if (mVelocityTracker == null) { - return 0; - } - mVelocityTracker.computeCurrentVelocity(1000); - float aX = mVelocityTracker.getXVelocity(); - float aY = mVelocityTracker.getYVelocity(); - float bX = lastX - mInitialTouchX; - float bY = lastY - mInitialTouchY; - float bLen = (float) Math.hypot(bX, bY); - // Project the velocity onto the distance vector: a * b / |b| - float projectedVelocity = (aX * bX + aY * bY) / bLen; - if (mTargetedView == mRightIcon) { - projectedVelocity = -projectedVelocity; - } - return projectedVelocity; - } - - public void onConfigurationChanged() { - initDimens(); - initIcons(); - } - - public void onRtlPropertiesChanged() { - initIcons(); - } - - public void reset(boolean animate) { - cancelAnimation(); - setTranslation(0.0f, true /* isReset */, animate); - mMotionCancelled = true; - if (mSwipingInProgress) { - mCallback.onSwipingAborted(); - mSwipingInProgress = false; - } - } - - public boolean isSwipingInProgress() { - return mSwipingInProgress; - } - - public void launchAffordance(boolean animate, boolean left) { - if (mSwipingInProgress) { - // We don't want to mess with the state if the user is actually swiping already. - return; - } - KeyguardAffordanceView targetView = left ? mLeftIcon : mRightIcon; - KeyguardAffordanceView otherView = left ? mRightIcon : mLeftIcon; - startSwiping(targetView); - - // Do not animate the circle expanding if the affordance isn't visible, - // otherwise the circle will be meaningless. - if (targetView.getVisibility() != View.VISIBLE) { - animate = false; - } - - if (animate) { - fling(0, false, !left); - updateIcon(otherView, 0.0f, 0, true, false, true, false); - } else { - mCallback.onAnimationToSideStarted(!left, mTranslation, 0); - mTranslation = left ? mCallback.getMaxTranslationDistance() - : mCallback.getMaxTranslationDistance(); - updateIcon(otherView, 0.0f, 0.0f, false, false, true, false); - targetView.instantFinishAnimation(); - mFlingEndListener.onAnimationEnd(null); - mAnimationEndRunnable.run(); - } - } - - public interface Callback { - - /** - * Notifies the callback when an animation to a side page was started. - * - * @param rightPage Is the page animated to the right page? - */ - void onAnimationToSideStarted(boolean rightPage, float translation, float vel); - - /** - * Notifies the callback the animation to a side page has ended. - */ - void onAnimationToSideEnded(); - - float getMaxTranslationDistance(); - - void onSwipingStarted(boolean rightIcon); - - void onSwipingAborted(); - - void onIconClicked(boolean rightIcon); - - KeyguardAffordanceView getLeftIcon(); - - KeyguardAffordanceView getRightIcon(); - - View getLeftPreview(); - - View getRightPreview(); - - /** - * @return The factor the minimum swipe amount should be multiplied with. - */ - float getAffordanceFalsingFactor(); - - boolean needsAntiFalsing(); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java index b43e9df79241..52c04b9de29a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java @@ -16,47 +16,30 @@ package com.android.systemui.statusbar.phone; -import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK; -import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; - import static com.android.systemui.controls.dagger.ControlsComponent.Visibility.AVAILABLE; import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset; -import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_BUTTON; -import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_UNLOCK; -import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_RIGHT_BUTTON; -import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_RIGHT_UNLOCK; import static com.android.systemui.wallet.controller.QuickAccessWalletController.WalletChangeEvent.DEFAULT_PAYMENT_APP_CHANGE; import static com.android.systemui.wallet.controller.QuickAccessWalletController.WalletChangeEvent.WALLET_PREFERENCE_CHANGE; -import android.app.ActivityOptions; import android.app.ActivityTaskManager; import android.app.admin.DevicePolicyManager; -import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; import android.content.res.ColorStateList; import android.content.res.Configuration; import android.graphics.drawable.Drawable; -import android.os.AsyncTask; -import android.os.Bundle; import android.os.RemoteException; import android.os.UserHandle; import android.service.quickaccesswallet.GetWalletCardsError; import android.service.quickaccesswallet.GetWalletCardsResponse; import android.service.quickaccesswallet.QuickAccessWalletClient; -import android.telecom.TelecomManager; -import android.text.TextUtils; import android.util.AttributeSet; import android.util.Log; import android.util.TypedValue; import android.view.View; import android.view.ViewGroup; import android.view.WindowInsets; -import android.view.WindowManager; -import android.view.accessibility.AccessibilityNodeInfo; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; @@ -64,81 +47,35 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.widget.LockPatternUtils; -import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.settingslib.Utils; -import com.android.systemui.ActivityIntentHelper; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.animation.Interpolators; -import com.android.systemui.assist.AssistManager; -import com.android.systemui.camera.CameraIntents; -import com.android.systemui.controls.ControlsServiceInfo; import com.android.systemui.controls.dagger.ControlsComponent; import com.android.systemui.controls.management.ControlsListingController; import com.android.systemui.controls.ui.ControlsActivity; import com.android.systemui.controls.ui.ControlsUiController; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.FalsingManager; -import com.android.systemui.plugins.IntentButtonProvider; -import com.android.systemui.plugins.IntentButtonProvider.IntentButton; -import com.android.systemui.plugins.IntentButtonProvider.IntentButton.IconState; import com.android.systemui.qrcodescanner.controller.QRCodeScannerController; -import com.android.systemui.statusbar.KeyguardAffordanceView; -import com.android.systemui.statusbar.policy.AccessibilityController; -import com.android.systemui.statusbar.policy.ExtensionController; -import com.android.systemui.statusbar.policy.ExtensionController.Extension; -import com.android.systemui.statusbar.policy.FlashlightController; import com.android.systemui.statusbar.policy.KeyguardStateController; -import com.android.systemui.statusbar.policy.PreviewInflater; -import com.android.systemui.tuner.LockscreenFragment.LockButtonFactory; -import com.android.systemui.tuner.TunerService; import com.android.systemui.wallet.controller.QuickAccessWalletController; -import java.util.List; - /** * Implementation for the bottom area of the Keyguard, including camera/phone affordance and status * text. */ -public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickListener, - KeyguardStateController.Callback, - AccessibilityController.AccessibilityStateChangedCallback { - - final static String TAG = "CentralSurfaces/KeyguardBottomAreaView"; - - public static final String CAMERA_LAUNCH_SOURCE_AFFORDANCE = "lockscreen_affordance"; - public static final String CAMERA_LAUNCH_SOURCE_WIGGLE = "wiggle_gesture"; - public static final String CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP = "power_double_tap"; - public static final String CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER = "lift_to_launch_ml"; - - public static final String EXTRA_CAMERA_LAUNCH_SOURCE - = "com.android.systemui.camera_launch_source"; - - private static final String LEFT_BUTTON_PLUGIN - = "com.android.systemui.action.PLUGIN_LOCKSCREEN_LEFT_BUTTON"; - private static final String RIGHT_BUTTON_PLUGIN - = "com.android.systemui.action.PLUGIN_LOCKSCREEN_RIGHT_BUTTON"; +public class KeyguardBottomAreaView extends FrameLayout { - private static final Intent PHONE_INTENT = new Intent(Intent.ACTION_DIAL); - private static final int DOZE_ANIMATION_STAGGER_DELAY = 48; + private static final String TAG = "CentralSurfaces/KeyguardBottomAreaView"; private static final int DOZE_ANIMATION_ELEMENT_DURATION = 250; - // TODO(b/179494051): May no longer be needed - private final boolean mShowLeftAffordance; - private final boolean mShowCameraAffordance; - - private KeyguardAffordanceView mRightAffordanceView; - private KeyguardAffordanceView mLeftAffordanceView; - private ImageView mWalletButton; private ImageView mQRCodeScannerButton; private ImageView mControlsButton; private boolean mHasCard = false; - private WalletCardRetriever mCardRetriever = new WalletCardRetriever(); + private final WalletCardRetriever mCardRetriever = new WalletCardRetriever(); private QuickAccessWalletController mQuickAccessWalletController; private QRCodeScannerController mQRCodeScannerController; private ControlsComponent mControlsComponent; @@ -148,54 +85,42 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL private ViewGroup mIndicationArea; private TextView mIndicationText; private TextView mIndicationTextBottom; - private ViewGroup mPreviewContainer; private ViewGroup mOverlayContainer; - private View mLeftPreview; - private View mCameraPreview; - private ActivityStarter mActivityStarter; private KeyguardStateController mKeyguardStateController; - private FlashlightController mFlashlightController; - private PreviewInflater mPreviewInflater; - private AccessibilityController mAccessibilityController; private CentralSurfaces mCentralSurfaces; - private KeyguardAffordanceHelper mAffordanceHelper; private FalsingManager mFalsingManager; - private boolean mUserSetupComplete; - private boolean mLeftIsVoiceAssist; - private Drawable mLeftAssistIcon; - - private IntentButton mRightButton = new DefaultRightButton(); - private Extension<IntentButton> mRightExtension; - private String mRightButtonStr; - private IntentButton mLeftButton = new DefaultLeftButton(); - private Extension<IntentButton> mLeftExtension; - private String mLeftButtonStr; private boolean mDozing; private int mIndicationBottomMargin; private int mIndicationPadding; private float mDarkAmount; private int mBurnInXOffset; private int mBurnInYOffset; - private ActivityIntentHelper mActivityIntentHelper; - private KeyguardUpdateMonitor mKeyguardUpdateMonitor; - - private ControlsListingController.ControlsListingCallback mListingCallback = - new ControlsListingController.ControlsListingCallback() { - public void onServicesUpdated(List<ControlsServiceInfo> serviceInfos) { - post(() -> { - boolean available = !serviceInfos.isEmpty(); - - if (available != mControlServicesAvailable) { - mControlServicesAvailable = available; - updateControlsVisibility(); - updateAffordanceColors(); - } - }); + + private final ControlsListingController.ControlsListingCallback mListingCallback = + serviceInfos -> post(() -> { + boolean available = !serviceInfos.isEmpty(); + + if (available != mControlServicesAvailable) { + mControlServicesAvailable = available; + updateControlsVisibility(); + updateAffordanceColors(); } - }; + }); + + private final KeyguardStateController.Callback mKeyguardStateCallback = + new KeyguardStateController.Callback() { + @Override + public void onKeyguardShowingChanged() { + if (mKeyguardStateController.isShowing()) { + if (mQuickAccessWalletController != null) { + mQuickAccessWalletController.queryWalletCards(mCardRetriever); + } + } + } + }; public KeyguardBottomAreaView(Context context) { this(context, null); @@ -212,43 +137,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL public KeyguardBottomAreaView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); - mShowLeftAffordance = getResources().getBoolean(R.bool.config_keyguardShowLeftAffordance); - mShowCameraAffordance = getResources() - .getBoolean(R.bool.config_keyguardShowCameraAffordance); } - private AccessibilityDelegate mAccessibilityDelegate = new AccessibilityDelegate() { - @Override - public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { - super.onInitializeAccessibilityNodeInfo(host, info); - String label = null; - if (host == mRightAffordanceView) { - label = getResources().getString(R.string.camera_label); - } else if (host == mLeftAffordanceView) { - if (mLeftIsVoiceAssist) { - label = getResources().getString(R.string.voice_assist_label); - } else { - label = getResources().getString(R.string.phone_label); - } - } - info.addAction(new AccessibilityAction(ACTION_CLICK, label)); - } - - @Override - public boolean performAccessibilityAction(View host, int action, Bundle args) { - if (action == ACTION_CLICK) { - if (host == mRightAffordanceView) { - launchCamera(CAMERA_LAUNCH_SOURCE_AFFORDANCE); - return true; - } else if (host == mLeftAffordanceView) { - launchLeftAffordance(); - return true; - } - } - return super.performAccessibilityAction(host, action, args); - } - }; - public void initFrom(KeyguardBottomAreaView oldBottomArea) { setCentralSurfaces(oldBottomArea.mCentralSurfaces); @@ -279,11 +169,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL @Override protected void onFinishInflate() { super.onFinishInflate(); - mPreviewInflater = new PreviewInflater(mContext, new LockPatternUtils(mContext), - new ActivityIntentHelper(mContext)); mOverlayContainer = findViewById(R.id.overlay_container); - mRightAffordanceView = findViewById(R.id.camera_button); - mLeftAffordanceView = findViewById(R.id.left_button); mWalletButton = findViewById(R.id.wallet_button); mQRCodeScannerButton = findViewById(R.id.qr_code_scanner_button); mControlsButton = findViewById(R.id.controls_button); @@ -295,18 +181,11 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL R.dimen.keyguard_indication_margin_bottom); mBurnInYOffset = getResources().getDimensionPixelSize( R.dimen.default_burn_in_prevention_offset); - updateCameraVisibility(); mKeyguardStateController = Dependency.get(KeyguardStateController.class); - mKeyguardStateController.addCallback(this); + mKeyguardStateController.addCallback(mKeyguardStateCallback); setClipChildren(false); setClipToPadding(false); - mRightAffordanceView.setOnClickListener(this); - mLeftAffordanceView.setOnClickListener(this); - initAccessibility(); mActivityStarter = Dependency.get(ActivityStarter.class); - mFlashlightController = Dependency.get(FlashlightController.class); - mAccessibilityController = Dependency.get(AccessibilityController.class); - mActivityIntentHelper = new ActivityIntentHelper(getContext()); mIndicationPadding = getResources().getDimensionPixelSize( R.dimen.keyguard_indication_area_padding); @@ -315,51 +194,18 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL updateControlsVisibility(); } - /** - * Set the container where the previews are rendered. - */ - public void setPreviewContainer(ViewGroup previewContainer) { - mPreviewContainer = previewContainer; - inflateCameraPreview(); - updateLeftAffordance(); - } - @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); - mAccessibilityController.addStateChangedCallback(this); - mRightExtension = Dependency.get(ExtensionController.class).newExtension(IntentButton.class) - .withPlugin(IntentButtonProvider.class, RIGHT_BUTTON_PLUGIN, - p -> p.getIntentButton()) - .withTunerFactory(new LockButtonFactory(mContext, LOCKSCREEN_RIGHT_BUTTON)) - .withDefault(() -> new DefaultRightButton()) - .withCallback(button -> setRightButton(button)) - .build(); - mLeftExtension = Dependency.get(ExtensionController.class).newExtension(IntentButton.class) - .withPlugin(IntentButtonProvider.class, LEFT_BUTTON_PLUGIN, - p -> p.getIntentButton()) - .withTunerFactory(new LockButtonFactory(mContext, LOCKSCREEN_LEFT_BUTTON)) - .withDefault(() -> new DefaultLeftButton()) - .withCallback(button -> setLeftButton(button)) - .build(); final IntentFilter filter = new IntentFilter(); filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED); - getContext().registerReceiverAsUser(mDevicePolicyReceiver, - UserHandle.ALL, filter, null, null); - mKeyguardUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class); - mKeyguardUpdateMonitor.registerCallback(mUpdateMonitorCallback); - mKeyguardStateController.addCallback(this); + mKeyguardStateController.addCallback(mKeyguardStateCallback); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); - mKeyguardStateController.removeCallback(this); - mAccessibilityController.removeStateChangedCallback(this); - mRightExtension.destroy(); - mLeftExtension.destroy(); - getContext().unregisterReceiver(mDevicePolicyReceiver); - mKeyguardUpdateMonitor.removeCallback(mUpdateMonitorCallback); + mKeyguardStateController.removeCallback(mKeyguardStateCallback); if (mQuickAccessWalletController != null) { mQuickAccessWalletController.unregisterWalletChangeObservers( @@ -378,11 +224,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL } } - private void initAccessibility() { - mLeftAffordanceView.setAccessibilityDelegate(mAccessibilityDelegate); - mRightAffordanceView.setAccessibilityDelegate(mAccessibilityDelegate); - } - @Override protected void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); @@ -404,19 +245,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL getResources().getDimensionPixelSize( com.android.internal.R.dimen.text_size_small_material)); - ViewGroup.LayoutParams lp = mRightAffordanceView.getLayoutParams(); - lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_width); - lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_height); - mRightAffordanceView.setLayoutParams(lp); - updateRightAffordanceIcon(); - - lp = mLeftAffordanceView.getLayoutParams(); - lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_width); - lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_height); - mLeftAffordanceView.setLayoutParams(lp); - updateLeftAffordanceIcon(); - - lp = mWalletButton.getLayoutParams(); + ViewGroup.LayoutParams lp = mWalletButton.getLayoutParams(); lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_width); lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_height); mWalletButton.setLayoutParams(lp); @@ -439,74 +268,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL updateAffordanceColors(); } - private void updateRightAffordanceIcon() { - IconState state = mRightButton.getIcon(); - mRightAffordanceView.setVisibility(!mDozing && state.isVisible ? View.VISIBLE : View.GONE); - if (state.drawable != mRightAffordanceView.getDrawable() - || state.tint != mRightAffordanceView.shouldTint()) { - mRightAffordanceView.setImageDrawable(state.drawable, state.tint); - } - mRightAffordanceView.setContentDescription(state.contentDescription); - } - public void setCentralSurfaces(CentralSurfaces centralSurfaces) { mCentralSurfaces = centralSurfaces; - updateCameraVisibility(); // in case onFinishInflate() was called too early - } - - public void setAffordanceHelper(KeyguardAffordanceHelper affordanceHelper) { - mAffordanceHelper = affordanceHelper; - } - - public void setUserSetupComplete(boolean userSetupComplete) { - mUserSetupComplete = userSetupComplete; - updateCameraVisibility(); - updateLeftAffordanceIcon(); - } - - private Intent getCameraIntent() { - return mRightButton.getIntent(); - } - - /** - * Resolves the intent to launch the camera application. - */ - public ResolveInfo resolveCameraIntent() { - return mContext.getPackageManager().resolveActivityAsUser(getCameraIntent(), - PackageManager.MATCH_DEFAULT_ONLY, - KeyguardUpdateMonitor.getCurrentUser()); - } - - private void updateCameraVisibility() { - if (mRightAffordanceView == null) { - // Things are not set up yet; reply hazy, ask again later - return; - } - mRightAffordanceView.setVisibility(!mDozing && mShowCameraAffordance - && mRightButton.getIcon().isVisible ? View.VISIBLE : View.GONE); - } - - /** - * Set an alternate icon for the left assist affordance (replace the mic icon) - */ - public void setLeftAssistIcon(Drawable drawable) { - mLeftAssistIcon = drawable; - updateLeftAffordanceIcon(); - } - - private void updateLeftAffordanceIcon() { - if (!mShowLeftAffordance || mDozing) { - mLeftAffordanceView.setVisibility(GONE); - return; - } - - IconState state = mLeftButton.getIcon(); - mLeftAffordanceView.setVisibility(state.isVisible ? View.VISIBLE : View.GONE); - if (state.drawable != mLeftAffordanceView.getDrawable() - || state.tint != mLeftAffordanceView.shouldTint()) { - mLeftAffordanceView.setImageDrawable(state.drawable, state.tint); - } - mLeftAffordanceView.setContentDescription(state.contentDescription); } private void updateWalletVisibility() { @@ -552,73 +315,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL } } - public boolean isLeftVoiceAssist() { - return mLeftIsVoiceAssist; - } - - private boolean isPhoneVisible() { - PackageManager pm = mContext.getPackageManager(); - return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY) - && pm.resolveActivity(PHONE_INTENT, 0) != null; - } - - @Override - public void onStateChanged(boolean accessibilityEnabled, boolean touchExplorationEnabled) { - mRightAffordanceView.setClickable(touchExplorationEnabled); - mLeftAffordanceView.setClickable(touchExplorationEnabled); - mRightAffordanceView.setFocusable(accessibilityEnabled); - mLeftAffordanceView.setFocusable(accessibilityEnabled); - } - - @Override - public void onClick(View v) { - if (v == mRightAffordanceView) { - launchCamera(CAMERA_LAUNCH_SOURCE_AFFORDANCE); - } else if (v == mLeftAffordanceView) { - launchLeftAffordance(); - } - } - - public void launchCamera(String source) { - final Intent intent = getCameraIntent(); - intent.putExtra(EXTRA_CAMERA_LAUNCH_SOURCE, source); - boolean wouldLaunchResolverActivity = mActivityIntentHelper.wouldLaunchResolverActivity( - intent, KeyguardUpdateMonitor.getCurrentUser()); - if (CameraIntents.isSecureCameraIntent(intent) && !wouldLaunchResolverActivity) { - AsyncTask.execute(new Runnable() { - @Override - public void run() { - // Normally an activity will set it's requested rotation - // animation on its window. However when launching an activity - // causes the orientation to change this is too late. In these cases - // the default animation is used. This doesn't look good for - // the camera (as it rotates the camera contents out of sync - // with physical reality). So, we ask the WindowManager to - // force the crossfade animation if an orientation change - // happens to occur during the launch. - ActivityOptions o = ActivityOptions.makeBasic(); - o.setDisallowEnterPictureInPictureWhileLaunching(true); - o.setRotationAnimationHint( - WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS); - try { - ActivityTaskManager.getService().startActivityAsUser( - null, getContext().getBasePackageName(), - getContext().getAttributionTag(), intent, - intent.resolveTypeIfNeeded(getContext().getContentResolver()), - null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, o.toBundle(), - UserHandle.CURRENT.getIdentifier()); - } catch (RemoteException e) { - Log.w(TAG, "Unable to start camera activity", e); - } - } - }); - } else { - // We need to delay starting the activity because ResolverActivity finishes itself if - // launched behind lockscreen. - mActivityStarter.startActivity(intent, false /* dismissShade */); - } - } - public void setDarkAmount(float darkAmount) { if (darkAmount == mDarkAmount) { return; @@ -627,77 +323,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL dozeTimeTick(); } - public void launchLeftAffordance() { - if (mLeftIsVoiceAssist) { - launchVoiceAssist(); - } else { - launchPhone(); - } - } - - @VisibleForTesting - void launchVoiceAssist() { - Runnable runnable = new Runnable() { - @Override - public void run() { - Dependency.get(AssistManager.class).launchVoiceAssistFromKeyguard(); - } - }; - if (!mKeyguardStateController.canDismissLockScreen()) { - Dependency.get(Dependency.BACKGROUND_EXECUTOR).execute(runnable); - } else { - boolean dismissShade = !TextUtils.isEmpty(mRightButtonStr) - && Dependency.get(TunerService.class).getValue(LOCKSCREEN_RIGHT_UNLOCK, 1) != 0; - mCentralSurfaces.executeRunnableDismissingKeyguard(runnable, null /* cancelAction */, - dismissShade, false /* afterKeyguardGone */, true /* deferred */); - } - } - - private boolean canLaunchVoiceAssist() { - return Dependency.get(AssistManager.class).canVoiceAssistBeLaunchedFromKeyguard(); - } - - private void launchPhone() { - final TelecomManager tm = TelecomManager.from(mContext); - if (tm.isInCall()) { - AsyncTask.execute(new Runnable() { - @Override - public void run() { - tm.showInCallScreen(false /* showDialpad */); - } - }); - } else { - boolean dismissShade = !TextUtils.isEmpty(mLeftButtonStr) - && Dependency.get(TunerService.class).getValue(LOCKSCREEN_LEFT_UNLOCK, 1) != 0; - mActivityStarter.startActivity(mLeftButton.getIntent(), dismissShade); - } - } - - - @Override - protected void onVisibilityChanged(View changedView, int visibility) { - super.onVisibilityChanged(changedView, visibility); - if (changedView == this && visibility == VISIBLE) { - updateCameraVisibility(); - } - } - - public KeyguardAffordanceView getLeftView() { - return mLeftAffordanceView; - } - - public KeyguardAffordanceView getRightView() { - return mRightAffordanceView; - } - - public View getLeftPreview() { - return mLeftPreview; - } - - public View getRightPreview() { - return mCameraPreview; - } - public View getIndicationArea() { return mIndicationArea; } @@ -707,66 +332,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL return false; } - @Override - public void onUnlockedChanged() { - updateCameraVisibility(); - } - - @Override - public void onKeyguardShowingChanged() { - if (mKeyguardStateController.isShowing()) { - if (mQuickAccessWalletController != null) { - mQuickAccessWalletController.queryWalletCards(mCardRetriever); - } - } - } - - private void inflateCameraPreview() { - if (mPreviewContainer == null) { - return; - } - View previewBefore = mCameraPreview; - boolean visibleBefore = false; - if (previewBefore != null) { - mPreviewContainer.removeView(previewBefore); - visibleBefore = previewBefore.getVisibility() == View.VISIBLE; - } - mCameraPreview = mPreviewInflater.inflatePreview(getCameraIntent()); - if (mCameraPreview != null) { - mPreviewContainer.addView(mCameraPreview); - mCameraPreview.setVisibility(visibleBefore ? View.VISIBLE : View.INVISIBLE); - } - if (mAffordanceHelper != null) { - mAffordanceHelper.updatePreviews(); - } - } - - private void updateLeftPreview() { - if (mPreviewContainer == null) { - return; - } - View previewBefore = mLeftPreview; - if (previewBefore != null) { - mPreviewContainer.removeView(previewBefore); - } - - if (mLeftIsVoiceAssist) { - if (Dependency.get(AssistManager.class).getVoiceInteractorComponentName() != null) { - mLeftPreview = mPreviewInflater.inflatePreviewFromService( - Dependency.get(AssistManager.class).getVoiceInteractorComponentName()); - } - } else { - mLeftPreview = mPreviewInflater.inflatePreview(mLeftButton.getIntent()); - } - if (mLeftPreview != null) { - mPreviewContainer.addView(mLeftPreview); - mLeftPreview.setVisibility(View.INVISIBLE); - } - if (mAffordanceHelper != null) { - mAffordanceHelper.updatePreviews(); - } - } - public void startFinishDozeAnimation() { long delay = 0; if (mWalletButton.getVisibility() == View.VISIBLE) { @@ -778,13 +343,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL if (mControlsButton.getVisibility() == View.VISIBLE) { startFinishDozeAnimationElement(mControlsButton, delay); } - if (mLeftAffordanceView.getVisibility() == View.VISIBLE) { - startFinishDozeAnimationElement(mLeftAffordanceView, delay); - delay += DOZE_ANIMATION_STAGGER_DELAY; - } - if (mRightAffordanceView.getVisibility() == View.VISIBLE) { - startFinishDozeAnimationElement(mRightAffordanceView, delay); - } } private void startFinishDozeAnimationElement(View element, long delay) { @@ -798,58 +356,9 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL .setDuration(DOZE_ANIMATION_ELEMENT_DURATION); } - private final BroadcastReceiver mDevicePolicyReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - post(new Runnable() { - @Override - public void run() { - updateCameraVisibility(); - } - }); - } - }; - - private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback = - new KeyguardUpdateMonitorCallback() { - @Override - public void onUserSwitchComplete(int userId) { - updateCameraVisibility(); - } - - @Override - public void onUserUnlocked() { - inflateCameraPreview(); - updateCameraVisibility(); - updateLeftAffordance(); - } - }; - - public void updateLeftAffordance() { - updateLeftAffordanceIcon(); - updateLeftPreview(); - } - - private void setRightButton(IntentButton button) { - mRightButton = button; - updateRightAffordanceIcon(); - updateCameraVisibility(); - inflateCameraPreview(); - } - - private void setLeftButton(IntentButton button) { - mLeftButton = button; - if (!(mLeftButton instanceof DefaultLeftButton)) { - mLeftIsVoiceAssist = false; - } - updateLeftAffordance(); - } - public void setDozing(boolean dozing, boolean animate) { mDozing = dozing; - updateCameraVisibility(); - updateLeftAffordanceIcon(); updateWalletVisibility(); updateControlsVisibility(); updateQRCodeButtonVisibility(); @@ -888,77 +397,12 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL * Sets the alpha of the indication areas and affordances, excluding the lock icon. */ public void setAffordanceAlpha(float alpha) { - mLeftAffordanceView.setAlpha(alpha); - mRightAffordanceView.setAlpha(alpha); mIndicationArea.setAlpha(alpha); mWalletButton.setAlpha(alpha); mQRCodeScannerButton.setAlpha(alpha); mControlsButton.setAlpha(alpha); } - private class DefaultLeftButton implements IntentButton { - - private IconState mIconState = new IconState(); - - @Override - public IconState getIcon() { - mLeftIsVoiceAssist = canLaunchVoiceAssist(); - if (mLeftIsVoiceAssist) { - mIconState.isVisible = mUserSetupComplete && mShowLeftAffordance; - if (mLeftAssistIcon == null) { - mIconState.drawable = mContext.getDrawable(R.drawable.ic_mic_26dp); - } else { - mIconState.drawable = mLeftAssistIcon; - } - mIconState.contentDescription = mContext.getString( - R.string.accessibility_voice_assist_button); - } else { - mIconState.isVisible = mUserSetupComplete && mShowLeftAffordance - && isPhoneVisible(); - mIconState.drawable = mContext.getDrawable( - com.android.internal.R.drawable.ic_phone); - mIconState.contentDescription = mContext.getString( - R.string.accessibility_phone_button); - } - return mIconState; - } - - @Override - public Intent getIntent() { - return PHONE_INTENT; - } - } - - private class DefaultRightButton implements IntentButton { - - private IconState mIconState = new IconState(); - - @Override - public IconState getIcon() { - boolean isCameraDisabled = (mCentralSurfaces != null) - && !mCentralSurfaces.isCameraAllowedByAdmin(); - mIconState.isVisible = !isCameraDisabled - && mShowCameraAffordance - && mUserSetupComplete - && resolveCameraIntent() != null; - mIconState.drawable = mContext.getDrawable(R.drawable.ic_camera_alt_24dp); - mIconState.contentDescription = - mContext.getString(R.string.accessibility_camera_button); - return mIconState; - } - - @Override - public Intent getIntent() { - boolean canDismissLs = mKeyguardStateController.canDismissLockScreen(); - boolean secure = mKeyguardStateController.isMethodSecure(); - if (secure && !canDismissLs) { - return CameraIntents.getSecureCameraIntent(getContext()); - } else { - return CameraIntents.getInsecureCameraIntent(getContext()); - } - } - } - @Override public WindowInsets onApplyWindowInsets(WindowInsets insets) { int bottom = insets.getDisplayCutout() != null diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightsOutNotifController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightsOutNotifController.java index c61510cce10e..6e98c49e6d43 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightsOutNotifController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightsOutNotifController.java @@ -32,6 +32,7 @@ import android.view.animation.AccelerateInterpolator; import androidx.lifecycle.Observer; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.statusbar.LetterboxDetails; import com.android.internal.view.AppearanceRegion; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.notification.collection.NotifLiveDataStore; @@ -144,7 +145,7 @@ public class LightsOutNotifController extends ViewController<View> { public void onSystemBarAttributesChanged(int displayId, @Appearance int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, @Behavior int behavior, InsetsVisibilities requestedVisibilities, - String packageName) { + String packageName, LetterboxDetails[] letterboxDetails) { if (displayId != mDisplayId) { return; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index b435055d1b16..5810d64a8bbc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -50,8 +50,6 @@ import android.app.ActivityManager; import android.app.Fragment; import android.app.StatusBarManager; import android.content.ContentResolver; -import android.content.pm.ResolveInfo; -import android.content.res.Configuration; import android.content.res.Resources; import android.database.ContentObserver; import android.graphics.Canvas; @@ -117,6 +115,7 @@ import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.animation.Interpolators; import com.android.systemui.animation.LaunchAnimator; import com.android.systemui.biometrics.AuthController; +import com.android.systemui.camera.CameraGestureHelper; import com.android.systemui.classifier.Classifier; import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.controls.dagger.ControlsComponent; @@ -145,7 +144,6 @@ import com.android.systemui.screenrecord.RecordingController; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.GestureRecorder; -import com.android.systemui.statusbar.KeyguardAffordanceView; import com.android.systemui.statusbar.KeyguardIndicationController; import com.android.systemui.statusbar.LockscreenShadeTransitionController; import com.android.systemui.statusbar.NotificationRemoteInputManager; @@ -252,9 +250,6 @@ public class NotificationPanelViewController extends PanelViewController { private final OnOverscrollTopChangedListener mOnOverscrollTopChangedListener = new OnOverscrollTopChangedListener(); - private final KeyguardAffordanceHelperCallback - mKeyguardAffordanceHelperCallback = - new KeyguardAffordanceHelperCallback(); private final OnEmptySpaceClickListener mOnEmptySpaceClickListener = new OnEmptySpaceClickListener(); @@ -333,8 +328,6 @@ public class NotificationPanelViewController extends PanelViewController { // Current max allowed keyguard notifications determined by measuring the panel private int mMaxAllowedKeyguardNotifications; - private ViewGroup mPreviewContainer; - private KeyguardAffordanceHelper mAffordanceHelper; private KeyguardQsUserSwitchController mKeyguardQsUserSwitchController; private KeyguardUserSwitcherController mKeyguardUserSwitcherController; private KeyguardStatusBarView mKeyguardStatusBar; @@ -434,8 +427,6 @@ public class NotificationPanelViewController extends PanelViewController { */ private boolean mQsAnimatorExpand; private boolean mIsLaunchTransitionFinished; - private boolean mIsLaunchTransitionRunning; - private Runnable mLaunchAnimationEndRunnable; private boolean mOnlyAffordanceInThisMotion; private ValueAnimator mQsSizeChangeAnimator; @@ -452,10 +443,8 @@ public class NotificationPanelViewController extends PanelViewController { private boolean mClosingWithAlphaFadeOut; private boolean mHeadsUpAnimatingAway; private boolean mLaunchingAffordance; - private boolean mAffordanceHasPreview; private final FalsingManager mFalsingManager; private final FalsingCollector mFalsingCollector; - private String mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_AFFORDANCE; private Runnable mHeadsUpExistenceChangedRunnable = () -> { setHeadsUpAnimatingAway(false); @@ -488,7 +477,6 @@ public class NotificationPanelViewController extends PanelViewController { private float mLinearDarkAmount; private boolean mPulsing; - private boolean mUserSetupComplete; private boolean mHideIconsDuringLaunchAnimation = true; private int mStackScrollerMeasuringPass; /** @@ -704,6 +692,8 @@ public class NotificationPanelViewController extends PanelViewController { } }; + private final CameraGestureHelper mCameraGestureHelper; + @Inject public NotificationPanelViewController(NotificationPanelView view, @Main Resources resources, @@ -775,7 +765,8 @@ public class NotificationPanelViewController extends PanelViewController { NotificationStackSizeCalculator notificationStackSizeCalculator, UnlockedScreenOffAnimationController unlockedScreenOffAnimationController, ShadeTransitionController shadeTransitionController, - SystemClock systemClock) { + SystemClock systemClock, + CameraGestureHelper cameraGestureHelper) { super(view, falsingManager, dozeLog, @@ -960,6 +951,7 @@ public class NotificationPanelViewController extends PanelViewController { } } }); + mCameraGestureHelper = cameraGestureHelper; } @VisibleForTesting @@ -1007,8 +999,6 @@ public class NotificationPanelViewController extends PanelViewController { mOnEmptySpaceClickListener); addTrackingHeadsUpListener(mNotificationStackScrollLayoutController::setTrackingHeadsUp); mKeyguardBottomArea = mView.findViewById(R.id.keyguard_bottom_area); - mPreviewContainer = mView.findViewById(R.id.preview_container); - mKeyguardBottomArea.setPreviewContainer(mPreviewContainer); initBottomArea(); @@ -1032,7 +1022,6 @@ public class NotificationPanelViewController extends PanelViewController { mView.setRtlChangeListener(layoutDirection -> { if (layoutDirection != mOldLayoutDirection) { - mAffordanceHelper.onRtlPropertiesChanged(); mOldLayoutDirection = layoutDirection; } }); @@ -1258,7 +1247,6 @@ public class NotificationPanelViewController extends PanelViewController { KeyguardBottomAreaView oldBottomArea = mKeyguardBottomArea; mKeyguardBottomArea = mKeyguardBottomAreaViewControllerProvider.get().getView(); mKeyguardBottomArea.initFrom(oldBottomArea); - mKeyguardBottomArea.setPreviewContainer(mPreviewContainer); mView.addView(mKeyguardBottomArea, index); initBottomArea(); mKeyguardIndicationController.setIndicationArea(mKeyguardBottomArea); @@ -1295,11 +1283,7 @@ public class NotificationPanelViewController extends PanelViewController { } private void initBottomArea() { - mAffordanceHelper = new KeyguardAffordanceHelper( - mKeyguardAffordanceHelperCallback, mView.getContext(), mFalsingManager); - mKeyguardBottomArea.setAffordanceHelper(mAffordanceHelper); mKeyguardBottomArea.setCentralSurfaces(mCentralSurfaces); - mKeyguardBottomArea.setUserSetupComplete(mUserSetupComplete); mKeyguardBottomArea.setFalsingManager(mFalsingManager); mKeyguardBottomArea.initWallet(mQuickAccessWalletController); mKeyguardBottomArea.initControls(mControlsComponent); @@ -1664,10 +1648,6 @@ public class NotificationPanelViewController extends PanelViewController { public void resetViews(boolean animate) { mIsLaunchTransitionFinished = false; mBlockTouches = false; - if (!mLaunchingAffordance) { - mAffordanceHelper.reset(false); - mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_AFFORDANCE; - } mCentralSurfaces.getGutsManager().closeAndSaveGuts(true /* leavebehind */, true /* force */, true /* controls */, -1 /* x */, -1 /* y */, true /* resetMenu */); if (animate && !isFullyCollapsed()) { @@ -2210,11 +2190,6 @@ public class NotificationPanelViewController extends PanelViewController { return isFullyCollapsed() || mBarState != StatusBarState.SHADE; } - @Override - protected boolean shouldGestureIgnoreXTouchSlop(float x, float y) { - return !mAffordanceHelper.isOnAffordanceIcon(x, y); - } - private void onQsTouch(MotionEvent event) { int pointerIndex = event.findPointerIndex(mTrackingPointer); if (pointerIndex < 0) { @@ -3377,9 +3352,6 @@ public class NotificationPanelViewController extends PanelViewController { mQsExpandImmediate = true; setShowShelfOnly(true); } - if (mBarState == KEYGUARD || mBarState == StatusBarState.SHADE_LOCKED) { - mAffordanceHelper.animateHideLeftRightIcon(); - } mNotificationStackScrollLayoutController.onPanelTrackingStarted(); cancelPendingPanelCollapse(); } @@ -3393,12 +3365,6 @@ public class NotificationPanelViewController extends PanelViewController { true /* animate */); } mNotificationStackScrollLayoutController.onPanelTrackingStopped(); - if (expand && (mBarState == KEYGUARD - || mBarState == StatusBarState.SHADE_LOCKED)) { - if (!mHintAnimationRunning) { - mAffordanceHelper.reset(true); - } - } // If we unlocked from a swipe, the user's finger might still be down after the // unlock animation ends. We need to wait until ACTION_UP to enable blurs again. @@ -3471,10 +3437,6 @@ public class NotificationPanelViewController extends PanelViewController { return mIsLaunchTransitionFinished; } - public boolean isLaunchTransitionRunning() { - return mIsLaunchTransitionRunning; - } - @Override public void setIsLaunchAnimationRunning(boolean running) { boolean wasRunning = mIsLaunchAnimationRunning; @@ -3493,10 +3455,6 @@ public class NotificationPanelViewController extends PanelViewController { } } - public void setLaunchTransitionEndRunnable(Runnable r) { - mLaunchAnimationEndRunnable = r; - } - private void updateDozingVisibilities(boolean animate) { mKeyguardBottomArea.setDozing(mDozing, animate); if (!mDozing && animate) { @@ -3675,30 +3633,13 @@ public class NotificationPanelViewController extends PanelViewController { && mBarState == StatusBarState.SHADE; } - public void launchCamera(boolean animate, int source) { - if (source == StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP) { - mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP; - } else if (source == StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE) { - mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_WIGGLE; - } else if (source == StatusBarManager.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER) { - mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER; - } else { - - // Default. - mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_AFFORDANCE; - } - - // If we are launching it when we are occluded already we don't want it to animate, - // nor setting these flags, since the occluded state doesn't change anymore, hence it's - // never reset. + /** Launches the camera. */ + public void launchCamera(int source) { if (!isFullyCollapsed()) { setLaunchingAffordance(true); - } else { - animate = false; } - mAffordanceHasPreview = mKeyguardBottomArea.getRightPreview() != null; - mAffordanceHelper.launchAffordance( - animate, mView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL); + + mCameraGestureHelper.launchCamera(source); } public void onAffordanceLaunchEnded() { @@ -3711,9 +3652,6 @@ public class NotificationPanelViewController extends PanelViewController { */ private void setLaunchingAffordance(boolean launchingAffordance) { mLaunchingAffordance = launchingAffordance; - mKeyguardAffordanceHelperCallback.getLeftIcon().setLaunchingAffordance(launchingAffordance); - mKeyguardAffordanceHelperCallback.getRightIcon().setLaunchingAffordance( - launchingAffordance); mKeyguardBypassController.setLaunchingAffordance(launchingAffordance); } @@ -3721,34 +3659,14 @@ public class NotificationPanelViewController extends PanelViewController { * Return true when a bottom affordance is launching an occluded activity with a splash screen. */ public boolean isLaunchingAffordanceWithPreview() { - return mLaunchingAffordance && mAffordanceHasPreview; + return mLaunchingAffordance; } /** * Whether the camera application can be launched for the camera launch gesture. */ public boolean canCameraGestureBeLaunched() { - if (!mCentralSurfaces.isCameraAllowedByAdmin()) { - return false; - } - - ResolveInfo resolveInfo = mKeyguardBottomArea.resolveCameraIntent(); - String - packageToLaunch = - (resolveInfo == null || resolveInfo.activityInfo == null) ? null - : resolveInfo.activityInfo.packageName; - return packageToLaunch != null && (mBarState != StatusBarState.SHADE || !isForegroundApp( - packageToLaunch)) && !mAffordanceHelper.isSwipingInProgress(); - } - - /** - * Return true if the applications with the package name is running in foreground. - * - * @param pkgName application package name. - */ - private boolean isForegroundApp(String pkgName) { - List<ActivityManager.RunningTaskInfo> tasks = mActivityManager.getRunningTasks(1); - return !tasks.isEmpty() && pkgName.equals(tasks.get(0).topActivity.getPackageName()); + return mCameraGestureHelper.canCameraGestureBeLaunched(mBarState); } public boolean hideStatusBarIconsWhenExpanded() { @@ -3827,9 +3745,6 @@ public class NotificationPanelViewController extends PanelViewController { @Override public void setTouchAndAnimationDisabled(boolean disabled) { super.setTouchAndAnimationDisabled(disabled); - if (disabled && mAffordanceHelper.isSwipingInProgress() && !mIsLaunchTransitionRunning) { - mAffordanceHelper.reset(false /* animate */); - } mNotificationStackScrollLayoutController.setAnimationsEnabled(!disabled); } @@ -3912,11 +3827,6 @@ public class NotificationPanelViewController extends PanelViewController { return mKeyguardBottomArea; } - public void setUserSetupComplete(boolean userSetupComplete) { - mUserSetupComplete = userSetupComplete; - mKeyguardBottomArea.setUserSetupComplete(userSetupComplete); - } - public void applyLaunchAnimationProgress(float linearProgress) { boolean hideIcons = LaunchAnimator.getProgress(ActivityLaunchAnimator.TIMINGS, linearProgress, ANIMATION_DELAY_ICON_FADE_IN, 100) == 0.0f; @@ -4271,10 +4181,6 @@ public class NotificationPanelViewController extends PanelViewController { mMetricsLogger.count(COUNTER_PANEL_OPEN_PEEK, 1); } boolean handled = false; - if ((!mIsExpanding || mHintAnimationRunning) && !mQsExpanded - && mBarState != StatusBarState.SHADE && !mDozing) { - handled |= mAffordanceHelper.onTouchEvent(event); - } if (mOnlyAffordanceInThisMotion) { return true; } @@ -4517,139 +4423,6 @@ public class NotificationPanelViewController extends PanelViewController { } } - private class KeyguardAffordanceHelperCallback implements KeyguardAffordanceHelper.Callback { - @Override - public void onAnimationToSideStarted(boolean rightPage, float translation, float vel) { - boolean - start = - mView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL ? rightPage - : !rightPage; - mIsLaunchTransitionRunning = true; - mLaunchAnimationEndRunnable = null; - float displayDensity = mCentralSurfaces.getDisplayDensity(); - int lengthDp = Math.abs((int) (translation / displayDensity)); - int velocityDp = Math.abs((int) (vel / displayDensity)); - if (start) { - mLockscreenGestureLogger.write(MetricsEvent.ACTION_LS_DIALER, lengthDp, velocityDp); - mLockscreenGestureLogger.log(LockscreenUiEvent.LOCKSCREEN_DIALER); - mFalsingCollector.onLeftAffordanceOn(); - if (mFalsingCollector.shouldEnforceBouncer()) { - mCentralSurfaces.executeRunnableDismissingKeyguard( - () -> mKeyguardBottomArea.launchLeftAffordance(), null, - true /* dismissShade */, false /* afterKeyguardGone */, - true /* deferred */); - } else { - mKeyguardBottomArea.launchLeftAffordance(); - } - } else { - if (KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_AFFORDANCE.equals( - mLastCameraLaunchSource)) { - mLockscreenGestureLogger.write( - MetricsEvent.ACTION_LS_CAMERA, lengthDp, velocityDp); - mLockscreenGestureLogger.log(LockscreenUiEvent.LOCKSCREEN_CAMERA); - } - mFalsingCollector.onCameraOn(); - if (mFalsingCollector.shouldEnforceBouncer()) { - mCentralSurfaces.executeRunnableDismissingKeyguard( - () -> mKeyguardBottomArea.launchCamera(mLastCameraLaunchSource), null, - true /* dismissShade */, false /* afterKeyguardGone */, - true /* deferred */); - } else { - mKeyguardBottomArea.launchCamera(mLastCameraLaunchSource); - } - } - mCentralSurfaces.startLaunchTransitionTimeout(); - mBlockTouches = true; - } - - @Override - public void onAnimationToSideEnded() { - mIsLaunchTransitionRunning = false; - mIsLaunchTransitionFinished = true; - if (mLaunchAnimationEndRunnable != null) { - mLaunchAnimationEndRunnable.run(); - mLaunchAnimationEndRunnable = null; - } - mCentralSurfaces.readyForKeyguardDone(); - } - - @Override - public float getMaxTranslationDistance() { - return (float) Math.hypot(mView.getWidth(), getHeight()); - } - - @Override - public void onSwipingStarted(boolean rightIcon) { - mFalsingCollector.onAffordanceSwipingStarted(rightIcon); - mView.requestDisallowInterceptTouchEvent(true); - mOnlyAffordanceInThisMotion = true; - mQsTracking = false; - } - - @Override - public void onSwipingAborted() { - mFalsingCollector.onAffordanceSwipingAborted(); - } - - @Override - public void onIconClicked(boolean rightIcon) { - if (mHintAnimationRunning) { - return; - } - mHintAnimationRunning = true; - mAffordanceHelper.startHintAnimation(rightIcon, () -> { - mHintAnimationRunning = false; - mCentralSurfaces.onHintFinished(); - }); - rightIcon = - mView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL ? !rightIcon - : rightIcon; - if (rightIcon) { - mCentralSurfaces.onCameraHintStarted(); - } else { - if (mKeyguardBottomArea.isLeftVoiceAssist()) { - mCentralSurfaces.onVoiceAssistHintStarted(); - } else { - mCentralSurfaces.onPhoneHintStarted(); - } - } - } - - @Override - public KeyguardAffordanceView getLeftIcon() { - return mView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL - ? mKeyguardBottomArea.getRightView() : mKeyguardBottomArea.getLeftView(); - } - - @Override - public KeyguardAffordanceView getRightIcon() { - return mView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL - ? mKeyguardBottomArea.getLeftView() : mKeyguardBottomArea.getRightView(); - } - - @Override - public View getLeftPreview() { - return mView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL - ? mKeyguardBottomArea.getRightPreview() : mKeyguardBottomArea.getLeftPreview(); - } - - @Override - public View getRightPreview() { - return mView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL - ? mKeyguardBottomArea.getLeftPreview() : mKeyguardBottomArea.getRightPreview(); - } - - @Override - public float getAffordanceFalsingFactor() { - return mCentralSurfaces.isWakeUpComingFromTouch() ? 1.5f : 1.0f; - } - - @Override - public boolean needsAntiFalsing() { - return mBarState == KEYGUARD; - } - } - private class OnEmptySpaceClickListener implements NotificationStackScrollLayout.OnEmptySpaceClickListener { @Override @@ -5104,15 +4877,6 @@ public class NotificationPanelViewController extends PanelViewController { } } - private class OnConfigurationChangedListener extends - PanelViewController.OnConfigurationChangedListener { - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - mAffordanceHelper.onConfigurationChanged(); - } - } - private class OnApplyWindowInsetsListener implements View.OnApplyWindowInsetsListener { public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) { // the same types of insets that are handled in NotificationShadeWindowView diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java index ed12b00cc644..d2fc1af010b9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java @@ -484,8 +484,6 @@ public abstract class PanelViewController { protected abstract boolean shouldGestureWaitForTouchSlop(); - protected abstract boolean shouldGestureIgnoreXTouchSlop(float x, float y); - protected void onTrackingStopped(boolean expand) { mTracking = false; mCentralSurfaces.onTrackingStopped(expand); @@ -1333,7 +1331,7 @@ public abstract class PanelViewController { if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { mGestureWaitForTouchSlop = shouldGestureWaitForTouchSlop(); - mIgnoreXTouchSlop = isFullyCollapsed() || shouldGestureIgnoreXTouchSlop(x, y); + mIgnoreXTouchSlop = true; } switch (event.getActionMasked()) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java deleted file mode 100644 index 3d317143eb51..000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2014 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.statusbar.policy; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.os.Bundle; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; - -import com.android.internal.widget.LockPatternUtils; -import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.systemui.ActivityIntentHelper; -import com.android.systemui.statusbar.phone.KeyguardPreviewContainer; - -import java.util.List; - -/** - * Utility class to inflate previews for phone and camera affordance. - */ -public class PreviewInflater { - - private static final String TAG = "PreviewInflater"; - - private static final String META_DATA_KEYGUARD_LAYOUT = "com.android.keyguard.layout"; - private final ActivityIntentHelper mActivityIntentHelper; - - private Context mContext; - private LockPatternUtils mLockPatternUtils; - - public PreviewInflater(Context context, LockPatternUtils lockPatternUtils, - ActivityIntentHelper activityIntentHelper) { - mContext = context; - mLockPatternUtils = lockPatternUtils; - mActivityIntentHelper = activityIntentHelper; - } - - public View inflatePreview(Intent intent) { - WidgetInfo info = getWidgetInfo(intent); - return inflatePreview(info); - } - - public View inflatePreviewFromService(ComponentName componentName) { - WidgetInfo info = getWidgetInfoFromService(componentName); - return inflatePreview(info); - } - - private KeyguardPreviewContainer inflatePreview(WidgetInfo info) { - if (info == null) { - return null; - } - View v = inflateWidgetView(info); - if (v == null) { - return null; - } - KeyguardPreviewContainer container = new KeyguardPreviewContainer(mContext, null); - container.addView(v); - return container; - } - - private View inflateWidgetView(WidgetInfo widgetInfo) { - View widgetView = null; - try { - Context appContext = mContext.createPackageContext( - widgetInfo.contextPackage, Context.CONTEXT_RESTRICTED); - LayoutInflater appInflater = (LayoutInflater) - appContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - appInflater = appInflater.cloneInContext(appContext); - widgetView = appInflater.inflate(widgetInfo.layoutId, null, false); - } catch (PackageManager.NameNotFoundException|RuntimeException e) { - Log.w(TAG, "Error creating widget view", e); - } - return widgetView; - } - - private WidgetInfo getWidgetInfoFromService(ComponentName componentName) { - PackageManager packageManager = mContext.getPackageManager(); - // Look for the preview specified in the service meta-data - try { - Bundle metaData = packageManager.getServiceInfo( - componentName, PackageManager.GET_META_DATA).metaData; - return getWidgetInfoFromMetaData(componentName.getPackageName(), metaData); - } catch (PackageManager.NameNotFoundException e) { - Log.w(TAG, "Failed to load preview; " + componentName.flattenToShortString() - + " not found", e); - } - return null; - } - - private WidgetInfo getWidgetInfoFromMetaData(String contextPackage, - Bundle metaData) { - if (metaData == null) { - return null; - } - int layoutId = metaData.getInt(META_DATA_KEYGUARD_LAYOUT); - if (layoutId == 0) { - return null; - } - WidgetInfo info = new WidgetInfo(); - info.contextPackage = contextPackage; - info.layoutId = layoutId; - return info; - } - - private WidgetInfo getWidgetInfo(Intent intent) { - PackageManager packageManager = mContext.getPackageManager(); - int flags = PackageManager.MATCH_DEFAULT_ONLY - | PackageManager.MATCH_DIRECT_BOOT_AWARE - | PackageManager.MATCH_DIRECT_BOOT_UNAWARE; - final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser( - intent, flags, KeyguardUpdateMonitor.getCurrentUser()); - if (appList.size() == 0) { - return null; - } - ResolveInfo resolved = packageManager.resolveActivityAsUser(intent, - flags | PackageManager.GET_META_DATA, - KeyguardUpdateMonitor.getCurrentUser()); - if (mActivityIntentHelper.wouldLaunchResolverActivity(resolved, appList)) { - return null; - } - if (resolved == null || resolved.activityInfo == null) { - return null; - } - return getWidgetInfoFromMetaData(resolved.activityInfo.packageName, - resolved.activityInfo.metaData); - } - - private static class WidgetInfo { - String contextPackage; - int layoutId; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java index 6af8e9e77d10..2e6664820fa7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java @@ -68,6 +68,7 @@ import com.android.systemui.GuestResetOrExitSessionReceiver; import com.android.systemui.GuestResumeSessionReceiver; import com.android.systemui.R; import com.android.systemui.SystemUISecondaryUserService; +import com.android.systemui.animation.DialogCuj; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.broadcast.BroadcastSender; @@ -116,6 +117,9 @@ public class UserSwitcherController implements Dumpable { private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF"; private static final long MULTI_USER_JOURNEY_TIMEOUT = 20000l; + private static final String INTERACTION_JANK_ADD_NEW_USER_TAG = "add_new_user"; + private static final String INTERACTION_JANK_EXIT_GUEST_MODE_TAG = "exit_guest_mode"; + protected final Context mContext; protected final UserTracker mUserTracker; protected final UserManager mUserManager; @@ -597,7 +601,9 @@ public class UserSwitcherController implements Dumpable { } mExitGuestDialog = new ExitGuestDialog(mContext, id, isGuestEphemeral, targetId); if (dialogShower != null) { - dialogShower.showDialog(mExitGuestDialog); + dialogShower.showDialog(mExitGuestDialog, new DialogCuj( + InteractionJankMonitor.CUJ_USER_DIALOG_OPEN, + INTERACTION_JANK_EXIT_GUEST_MODE_TAG)); } else { mExitGuestDialog.show(); } @@ -609,7 +615,11 @@ public class UserSwitcherController implements Dumpable { } mAddUserDialog = new AddUserDialog(mContext); if (dialogShower != null) { - dialogShower.showDialog(mAddUserDialog); + dialogShower.showDialog(mAddUserDialog, + new DialogCuj( + InteractionJankMonitor.CUJ_USER_DIALOG_OPEN, + INTERACTION_JANK_ADD_NEW_USER_TAG + )); } else { mAddUserDialog.show(); } diff --git a/packages/SystemUI/src/com/android/systemui/user/CreateUserActivity.java b/packages/SystemUI/src/com/android/systemui/user/CreateUserActivity.java index cc6bf6a70d4e..f01712653e1b 100644 --- a/packages/SystemUI/src/com/android/systemui/user/CreateUserActivity.java +++ b/packages/SystemUI/src/com/android/systemui/user/CreateUserActivity.java @@ -31,6 +31,7 @@ import androidx.annotation.Nullable; import com.android.settingslib.users.EditUserInfoController; import com.android.systemui.R; +import com.android.systemui.plugins.ActivityStarter; import javax.inject.Inject; @@ -55,15 +56,18 @@ public class CreateUserActivity extends Activity { private final UserCreator mUserCreator; private final EditUserInfoController mEditUserInfoController; private final IActivityManager mActivityManager; + private final ActivityStarter mActivityStarter; private Dialog mSetupUserDialog; @Inject public CreateUserActivity(UserCreator userCreator, - EditUserInfoController editUserInfoController, IActivityManager activityManager) { + EditUserInfoController editUserInfoController, IActivityManager activityManager, + ActivityStarter activityStarter) { mUserCreator = userCreator; mEditUserInfoController = editUserInfoController; mActivityManager = activityManager; + mActivityStarter = activityStarter; } @Override @@ -104,10 +108,7 @@ public class CreateUserActivity extends Activity { return mEditUserInfoController.createDialog( this, - (intent, requestCode) -> { - mEditUserInfoController.startingActivityForResult(); - startActivityForResult(intent, requestCode); - }, + this::startActivity, null, defaultUserName, getString(com.android.settingslib.R.string.user_add_user), @@ -160,4 +161,17 @@ public class CreateUserActivity extends Activity { Log.e(TAG, "Couldn't switch user.", e); } } + + /** + * Lambda to start activity from an intent. Ensures that device is unlocked first. + * @param intent + * @param requestCode + */ + private void startActivity(Intent intent, int requestCode) { + mActivityStarter.dismissKeyguardThenExecute(() -> { + mEditUserInfoController.startingActivityForResult(); + startActivityForResult(intent, requestCode); + return true; + }, /* cancel= */ null, /* afterKeyguardGone= */ true); + } } diff --git a/packages/SystemUI/src/com/android/systemui/util/AsyncActivityLauncher.kt b/packages/SystemUI/src/com/android/systemui/util/AsyncActivityLauncher.kt new file mode 100644 index 000000000000..80d0e4b90359 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/util/AsyncActivityLauncher.kt @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2022 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.util + +import android.app.IActivityTaskManager +import android.app.WaitResult +import android.content.Context +import android.content.Intent +import android.os.Bundle +import android.os.UserHandle +import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.dagger.qualifiers.UiBackground +import java.util.concurrent.Executor +import javax.inject.Inject + +/** + * Helper class that allows to launch an activity and asynchronously wait + * for it to be launched. This class uses application context, so the intent + * will be launched with FLAG_ACTIVITY_NEW_TASK. + */ +class AsyncActivityLauncher @Inject constructor( + private val context: Context, + private val activityTaskManager: IActivityTaskManager, + @UiBackground private val backgroundExecutor: Executor, + @Main private val mainExecutor: Executor +) { + + private var pendingCallback: ((WaitResult) -> Unit)? = null + + /** + * Starts activity and notifies about the result using the provided [callback]. + * If there is already pending activity launch the call will be ignored. + * + * @return true if launch has started, false otherwise + */ + fun startActivityAsUser(intent: Intent, userHandle: UserHandle, + activityOptions: Bundle? = null, + callback: (WaitResult) -> Unit): Boolean { + if (pendingCallback != null) return false + + pendingCallback = callback + + intent.flags = intent.flags or Intent.FLAG_ACTIVITY_NEW_TASK + + backgroundExecutor.execute { + val waitResult = activityTaskManager.startActivityAndWait( + /* caller = */ null, + /* callingPackage = */ context.packageName, + /* callingFeatureId = */ context.attributionTag, + /* intent = */ intent, + /* resolvedType = */ null, + /* resultTo = */ null, + /* resultWho = */ null, + /* requestCode = */ 0, + /* flags = */ 0, + /* profilerInfo = */ null, + /* options = */ activityOptions, + /* userId = */ userHandle.identifier + ) + mainExecutor.execute { + pendingCallback?.invoke(waitResult) + } + } + + return true + } + + /** + * Cancels pending activity launches. It guarantees that the callback won't be fired + * but the activity will be launched anyway. + */ + fun destroy() { + pendingCallback = null + } +} diff --git a/packages/SystemUI/src/com/android/systemui/util/service/ObservableServiceConnection.java b/packages/SystemUI/src/com/android/systemui/util/service/ObservableServiceConnection.java index c57dbe37ca5f..064c224b0568 100644 --- a/packages/SystemUI/src/com/android/systemui/util/service/ObservableServiceConnection.java +++ b/packages/SystemUI/src/com/android/systemui/util/service/ObservableServiceConnection.java @@ -155,11 +155,6 @@ public class ObservableServiceConnection<T> implements ServiceConnection { * Disconnect from the service if bound. */ public void unbind() { - if (!mBoundCalled) { - return; - } - mBoundCalled = false; - mContext.unbindService(this); onDisconnected(DISCONNECT_REASON_UNBIND); } @@ -210,12 +205,15 @@ public class ObservableServiceConnection<T> implements ServiceConnection { Log.d(TAG, "onDisconnected:" + reason); } + // If not bound or already unbound, do not proceed setting reason, unbinding, and + // notifying if (!mBoundCalled) { return; } + mBoundCalled = false; mLastDisconnectReason = Optional.of(reason); - unbind(); + mContext.unbindService(this); mProxy = null; applyToCallbacksLocked(callback-> callback.onDisconnected(this, diff --git a/packages/SystemUI/src/com/android/systemui/util/service/PersistentConnectionManager.java b/packages/SystemUI/src/com/android/systemui/util/service/PersistentConnectionManager.java index 292c062369c1..6e19bed49626 100644 --- a/packages/SystemUI/src/com/android/systemui/util/service/PersistentConnectionManager.java +++ b/packages/SystemUI/src/com/android/systemui/util/service/PersistentConnectionManager.java @@ -72,6 +72,11 @@ public class PersistentConnectionManager<T> { @Override public void onDisconnected(ObservableServiceConnection connection, int reason) { + // Do not attempt to reconnect if we were manually unbound + if (reason == ObservableServiceConnection.DISCONNECT_REASON_UNBIND) { + return; + } + if (mSystemClock.currentTimeMillis() - mStartTime > mMinConnectionDuration) { initiateConnectionAttempt(); } else { diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt index 1e2074bfab98..4218e0904c43 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt @@ -170,19 +170,27 @@ class DialogLaunchAnimatorTest : SysuiTestCase() { @Test fun testCujSpecificationLogsInteraction() { val touchSurface = createTouchSurface() - return runOnMainThreadAndWaitForIdleSync { + runOnMainThreadAndWaitForIdleSync { val dialog = TestDialog(context) dialogLaunchAnimator.showFromView( - dialog, touchSurface, - cuj = DialogCuj(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN) - ) + dialog, touchSurface, cuj = DialogCuj(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN)) } - verify(interactionJankMonitor).begin( - any() - ) - verify(interactionJankMonitor) - .end(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN) + verify(interactionJankMonitor).begin(any()) + verify(interactionJankMonitor).end(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN) + } + + @Test + fun testShowFromDialogCujSpecificationLogsInteraction() { + val firstDialog = createAndShowDialog() + runOnMainThreadAndWaitForIdleSync { + val dialog = TestDialog(context) + dialogLaunchAnimator.showFromDialog( + dialog, firstDialog, cuj = DialogCuj(InteractionJankMonitor.CUJ_USER_DIALOG_OPEN)) + dialog + } + verify(interactionJankMonitor).begin(any()) + verify(interactionJankMonitor).end(InteractionJankMonitor.CUJ_USER_DIALOG_OPEN) } private fun createAndShowDialog(): TestDialog { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/charging/WiredChargingRippleControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/charging/WiredChargingRippleControllerTest.kt index d0cf792b698d..6978490a1252 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/charging/WiredChargingRippleControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/charging/WiredChargingRippleControllerTest.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.statusbar.charging +package com.android.systemui.charging import android.testing.AndroidTestingRunner import android.view.View @@ -24,6 +24,7 @@ import com.android.internal.logging.UiEventLogger import com.android.systemui.SysuiTestCase import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags +import com.android.systemui.ripple.RippleView import com.android.systemui.statusbar.commandline.CommandRegistry import com.android.systemui.statusbar.policy.BatteryController import com.android.systemui.statusbar.policy.ConfigurationController @@ -50,7 +51,7 @@ class WiredChargingRippleControllerTest : SysuiTestCase() { @Mock private lateinit var batteryController: BatteryController @Mock private lateinit var featureFlags: FeatureFlags @Mock private lateinit var configurationController: ConfigurationController - @Mock private lateinit var rippleView: ChargingRippleView + @Mock private lateinit var rippleView: RippleView @Mock private lateinit var windowManager: WindowManager @Mock private lateinit var uiEventLogger: UiEventLogger private val systemClock = FakeSystemClock() diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java index a80aed7a6d18..9b665555562a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java @@ -203,6 +203,13 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { mViewMediator.mViewMediatorCallback.getBouncerPromptReason()); } + @Test + public void testHideSurfaceBehindKeyguardMarksKeyguardNotGoingAway() { + mViewMediator.hideSurfaceBehindKeyguard(); + + verify(mKeyguardStateController).notifyKeyguardGoingAway(false); + } + private void createAndStartViewMediator() { mViewMediator = new KeyguardViewMediator( mContext, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java index fc4d9c42eb49..cf7f8dd26647 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java @@ -41,6 +41,7 @@ import android.view.WindowInsetsController.Behavior; import androidx.test.filters.SmallTest; +import com.android.internal.statusbar.LetterboxDetails; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.view.AppearanceRegion; import com.android.systemui.SysuiTestCase; @@ -53,6 +54,13 @@ import org.junit.Test; @SmallTest public class CommandQueueTest extends SysuiTestCase { + private static final LetterboxDetails[] TEST_LETTERBOX_DETAILS = new LetterboxDetails[] { + new LetterboxDetails( + /* letterboxInnerBounds= */ new Rect(100, 0, 200, 500), + /* letterboxFullBounds= */ new Rect(0, 0, 500, 100), + /* appAppearance= */ 123) + }; + private CommandQueue mCommandQueue; private Callbacks mCallbacks; private static final int SECONDARY_DISPLAY = 1; @@ -127,25 +135,27 @@ public class CommandQueueTest extends SysuiTestCase { public void testOnSystemBarAttributesChanged() { doTestOnSystemBarAttributesChanged(DEFAULT_DISPLAY, 1, new AppearanceRegion[]{new AppearanceRegion(2, new Rect())}, false, - BEHAVIOR_DEFAULT, new InsetsVisibilities(), "test"); + BEHAVIOR_DEFAULT, new InsetsVisibilities(), "test", TEST_LETTERBOX_DETAILS); } @Test public void testOnSystemBarAttributesChangedForSecondaryDisplay() { doTestOnSystemBarAttributesChanged(SECONDARY_DISPLAY, 1, new AppearanceRegion[]{new AppearanceRegion(2, new Rect())}, false, - BEHAVIOR_DEFAULT, new InsetsVisibilities(), "test"); + BEHAVIOR_DEFAULT, new InsetsVisibilities(), "test", TEST_LETTERBOX_DETAILS); } private void doTestOnSystemBarAttributesChanged(int displayId, @Appearance int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, - @Behavior int behavior, InsetsVisibilities requestedVisibilities, String packageName) { + @Behavior int behavior, InsetsVisibilities requestedVisibilities, String packageName, + LetterboxDetails[] letterboxDetails) { mCommandQueue.onSystemBarAttributesChanged(displayId, appearance, appearanceRegions, - navbarColorManagedByIme, behavior, requestedVisibilities, packageName); + navbarColorManagedByIme, behavior, requestedVisibilities, packageName, + letterboxDetails); waitForIdleSync(); verify(mCallbacks).onSystemBarAttributesChanged(eq(displayId), eq(appearance), eq(appearanceRegions), eq(navbarColorManagedByIme), eq(behavior), - eq(requestedVisibilities), eq(packageName)); + eq(requestedVisibilities), eq(packageName), eq(letterboxDetails)); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java index 3f56cf9cb8ad..54cbe24df732 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java @@ -206,11 +206,9 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase { @Test public void testDoNotRunFilterOnNewPipeline() { - when(mFlags.isNewPipelineEnabled()).thenReturn(true); // WHEN this entry should be filtered out NotificationEntry entry = createNotification(IMPORTANCE_DEFAULT); mNotifInterruptionStateProvider.shouldHeadsUp(entry); - verify(mFlags, times(1)).isNewPipelineEnabled(); verify(mNotificationFilter, times(0)).shouldFilterOut(eq(entry)); } @@ -326,7 +324,8 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase { public void testShouldNotHeadsUp_filtered() throws RemoteException { ensureStateForHeadsUpWhenAwake(); // Make canAlertCommon false by saying it's filtered out - when(mNotificationFilter.shouldFilterOut(any())).thenReturn(true); + when(mKeyguardNotificationVisibilityProvider.shouldHideNotification(any())) + .thenReturn(true); NotificationEntry entry = createNotification(IMPORTANCE_HIGH); assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse(); @@ -504,7 +503,8 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase { ensureStateForBubbleUp(); // Make canAlertCommon false by saying it's filtered out - when(mNotificationFilter.shouldFilterOut(any())).thenReturn(true); + when(mKeyguardNotificationVisibilityProvider.shouldHideNotification(any())) + .thenReturn(true); assertThat(mNotifInterruptionStateProvider.shouldBubbleUp(createBubble())).isFalse(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerLegacyTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerLegacyTest.java deleted file mode 100644 index 429d2ed36cc7..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerLegacyTest.java +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright (C) 2017 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.statusbar.notification.logging; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.Notification; -import android.os.Handler; -import android.os.Looper; -import android.os.UserHandle; -import android.testing.AndroidTestingRunner; -import android.testing.TestableLooper; - -import androidx.test.filters.SmallTest; - -import com.android.internal.logging.InstanceId; -import com.android.internal.statusbar.IStatusBarService; -import com.android.internal.statusbar.NotificationVisibility; -import com.android.systemui.SysuiTestCase; -import com.android.systemui.statusbar.NotificationListener; -import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.StatusBarStateControllerImpl; -import com.android.systemui.statusbar.notification.NotifPipelineFlags; -import com.android.systemui.statusbar.notification.NotificationEntryManager; -import com.android.systemui.statusbar.notification.collection.NotifLiveData; -import com.android.systemui.statusbar.notification.collection.NotifLiveDataStore; -import com.android.systemui.statusbar.notification.collection.NotifPipeline; -import com.android.systemui.statusbar.notification.collection.NotificationEntry; -import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; -import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider; -import com.android.systemui.statusbar.notification.logging.nano.Notifications; -import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; -import com.android.systemui.statusbar.notification.stack.NotificationListContainer; -import com.android.systemui.util.concurrency.FakeExecutor; -import com.android.systemui.util.time.FakeSystemClock; - -import com.google.android.collect.Lists; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; - -import java.util.List; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.Executor; - -@SmallTest -@RunWith(AndroidTestingRunner.class) -@TestableLooper.RunWithLooper -public class NotificationLoggerLegacyTest extends SysuiTestCase { - private static final String TEST_PACKAGE_NAME = "test"; - private static final int TEST_UID = 0; - - @Mock private NotificationListContainer mListContainer; - @Mock private IStatusBarService mBarService; - @Mock private ExpandableNotificationRow mRow; - @Mock private NotificationLogger.ExpansionStateLogger mExpansionStateLogger; - - // Dependency mocks: - @Mock private NotifPipelineFlags mNotifPipelineFlags; - @Mock private NotifLiveDataStore mNotifLiveDataStore; - @Mock private NotifLiveData<List<NotificationEntry>> mActiveNotifList; - @Mock private NotificationVisibilityProvider mVisibilityProvider; - @Mock private NotificationEntryManager mEntryManager; - @Mock private NotifPipeline mNotifPipeline; - @Mock private NotificationListener mListener; - - private NotificationEntry mEntry; - private TestableNotificationLogger mLogger; - private ConcurrentLinkedQueue<AssertionError> mErrorQueue = new ConcurrentLinkedQueue<>(); - private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock()); - private NotificationPanelLoggerFake mNotificationPanelLoggerFake = - new NotificationPanelLoggerFake(); - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - when(mNotifLiveDataStore.getActiveNotifList()).thenReturn(mActiveNotifList); - - mEntry = new NotificationEntryBuilder() - .setPkg(TEST_PACKAGE_NAME) - .setOpPkg(TEST_PACKAGE_NAME) - .setUid(TEST_UID) - .setNotification(new Notification()) - .setUser(UserHandle.CURRENT) - .setInstanceId(InstanceId.fakeInstanceId(1)) - .build(); - mEntry.setRow(mRow); - - mLogger = new TestableNotificationLogger( - mListener, - mUiBgExecutor, - mNotifPipelineFlags, - mNotifLiveDataStore, - mVisibilityProvider, - mEntryManager, - mNotifPipeline, - mock(StatusBarStateControllerImpl.class), - mBarService, - mExpansionStateLogger - ); - mLogger.setUpWithContainer(mListContainer); - verify(mEntryManager).addNotificationEntryListener(any()); - verify(mNotifPipeline, never()).addCollectionListener(any()); - } - - @After - public void tearDown() { - mLogger.mHandler.removeCallbacksAndMessages(null); - } - - @Test - public void testOnChildLocationsChangedReportsVisibilityChanged() throws Exception { - NotificationVisibility[] newlyVisibleKeys = { - NotificationVisibility.obtain(mEntry.getKey(), 0, 1, true) - }; - NotificationVisibility[] noLongerVisibleKeys = {}; - doAnswer(invocation -> { - try { - assertArrayEquals(newlyVisibleKeys, - (NotificationVisibility[]) invocation.getArguments()[0]); - assertArrayEquals(noLongerVisibleKeys, - (NotificationVisibility[]) invocation.getArguments()[1]); - } catch (AssertionError error) { - mErrorQueue.offer(error); - } - return null; - } - ).when(mBarService).onNotificationVisibilityChanged(any(NotificationVisibility[].class), - any(NotificationVisibility[].class)); - - when(mListContainer.isInVisibleLocation(any())).thenReturn(true); - when(mActiveNotifList.getValue()).thenReturn(Lists.newArrayList(mEntry)); - mLogger.getChildLocationsChangedListenerForTest().onChildLocationsChanged(); - TestableLooper.get(this).processAllMessages(); - mUiBgExecutor.runAllReady(); - - if (!mErrorQueue.isEmpty()) { - throw mErrorQueue.poll(); - } - - // |mEntry| won't change visibility, so it shouldn't be reported again: - Mockito.reset(mBarService); - mLogger.getChildLocationsChangedListenerForTest().onChildLocationsChanged(); - TestableLooper.get(this).processAllMessages(); - mUiBgExecutor.runAllReady(); - - verify(mBarService, never()).onNotificationVisibilityChanged(any(), any()); - } - - @Test - public void testStoppingNotificationLoggingReportsCurrentNotifications() - throws Exception { - when(mListContainer.isInVisibleLocation(any())).thenReturn(true); - when(mActiveNotifList.getValue()).thenReturn(Lists.newArrayList(mEntry)); - mLogger.getChildLocationsChangedListenerForTest().onChildLocationsChanged(); - TestableLooper.get(this).processAllMessages(); - mUiBgExecutor.runAllReady(); - Mockito.reset(mBarService); - - setStateAsleep(); - mLogger.onDozingChanged(false); // Wake to lockscreen - mLogger.onDozingChanged(true); // And go back to sleep, turning off logging - mUiBgExecutor.runAllReady(); - // The visibility objects are recycled by NotificationLogger, so we can't use specific - // matchers here. - verify(mBarService, times(1)).onNotificationVisibilityChanged(any(), any()); - } - - private void setStateAsleep() { - mLogger.onPanelExpandedChanged(true); - mLogger.onDozingChanged(true); - mLogger.onStateChanged(StatusBarState.KEYGUARD); - } - - private void setStateAwake() { - mLogger.onPanelExpandedChanged(false); - mLogger.onDozingChanged(false); - mLogger.onStateChanged(StatusBarState.SHADE); - } - - @Test - public void testLogPanelShownOnWake() { - when(mActiveNotifList.getValue()).thenReturn(Lists.newArrayList(mEntry)); - setStateAsleep(); - mLogger.onDozingChanged(false); // Wake to lockscreen - assertEquals(1, mNotificationPanelLoggerFake.getCalls().size()); - assertTrue(mNotificationPanelLoggerFake.get(0).isLockscreen); - assertEquals(1, mNotificationPanelLoggerFake.get(0).list.notifications.length); - Notifications.Notification n = mNotificationPanelLoggerFake.get(0).list.notifications[0]; - assertEquals(TEST_PACKAGE_NAME, n.packageName); - assertEquals(TEST_UID, n.uid); - assertEquals(1, n.instanceId); - assertFalse(n.isGroupSummary); - assertEquals(Notifications.Notification.SECTION_ALERTING, n.section); - } - - @Test - public void testLogPanelShownOnShadePull() { - when(mActiveNotifList.getValue()).thenReturn(Lists.newArrayList(mEntry)); - setStateAwake(); - // Now expand panel - mLogger.onPanelExpandedChanged(true); - assertEquals(1, mNotificationPanelLoggerFake.getCalls().size()); - assertFalse(mNotificationPanelLoggerFake.get(0).isLockscreen); - assertEquals(1, mNotificationPanelLoggerFake.get(0).list.notifications.length); - Notifications.Notification n = mNotificationPanelLoggerFake.get(0).list.notifications[0]; - assertEquals(TEST_PACKAGE_NAME, n.packageName); - assertEquals(TEST_UID, n.uid); - assertEquals(1, n.instanceId); - assertFalse(n.isGroupSummary); - assertEquals(Notifications.Notification.SECTION_ALERTING, n.section); - } - - - @Test - public void testLogPanelShownHandlesNullInstanceIds() { - // Construct a NotificationEntry like mEntry, but with a null instance id. - NotificationEntry entry = new NotificationEntryBuilder() - .setPkg(TEST_PACKAGE_NAME) - .setOpPkg(TEST_PACKAGE_NAME) - .setUid(TEST_UID) - .setNotification(new Notification()) - .setUser(UserHandle.CURRENT) - .build(); - entry.setRow(mRow); - - when(mActiveNotifList.getValue()).thenReturn(Lists.newArrayList(entry)); - setStateAsleep(); - mLogger.onDozingChanged(false); // Wake to lockscreen - assertEquals(1, mNotificationPanelLoggerFake.getCalls().size()); - assertEquals(1, mNotificationPanelLoggerFake.get(0).list.notifications.length); - Notifications.Notification n = mNotificationPanelLoggerFake.get(0).list.notifications[0]; - assertEquals(0, n.instanceId); - } - - private class TestableNotificationLogger extends NotificationLogger { - - TestableNotificationLogger(NotificationListener notificationListener, - Executor uiBgExecutor, - NotifPipelineFlags notifPipelineFlags, - NotifLiveDataStore notifLiveDataStore, - NotificationVisibilityProvider visibilityProvider, - NotificationEntryManager entryManager, - NotifPipeline notifPipeline, - StatusBarStateControllerImpl statusBarStateController, - IStatusBarService barService, - ExpansionStateLogger expansionStateLogger) { - super( - notificationListener, - uiBgExecutor, - notifPipelineFlags, - notifLiveDataStore, - visibilityProvider, - entryManager, - notifPipeline, - statusBarStateController, - expansionStateLogger, - mNotificationPanelLoggerFake - ); - mBarService = barService; - mHandler.removeCallbacksAndMessages(null); - // Make this on the current thread so we can wait for it during tests. - mHandler = Handler.createAsync(Looper.myLooper()); - } - - OnChildLocationsChangedListener getChildLocationsChangedListenerForTest() { - return mNotificationLocationsChangedListener; - } - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java index b69bd8dfca9c..8a7b9d3b6024 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java @@ -103,7 +103,6 @@ public class NotificationLoggerTest extends SysuiTestCase { @Before public void setUp() { MockitoAnnotations.initMocks(this); - when(mNotifPipelineFlags.isNewPipelineEnabled()).thenReturn(true); when(mNotifLiveDataStore.getActiveNotifList()).thenReturn(mActiveNotifEntries); mEntry = new NotificationEntryBuilder() @@ -278,10 +277,8 @@ public class NotificationLoggerTest extends SysuiTestCase { super( notificationListener, uiBgExecutor, - notifPipelineFlags, notifLiveDataStore, visibilityProvider, - entryManager, notifPipeline, statusBarStateController, expansionStateLogger, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt index 275dbfd516e4..8fd6842911de 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt @@ -15,6 +15,7 @@ import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager import com.google.common.truth.Truth.assertThat import junit.framework.Assert.assertFalse import junit.framework.Assert.assertTrue +import junit.framework.Assert.assertEquals import org.junit.Before import org.junit.Test import org.mockito.Mockito.mock @@ -164,4 +165,178 @@ class StackScrollAlgorithmTest : SysuiTestCase() { stackScrollAlgorithm.updateViewWithShelf(expandableView, expandableViewState, shelfStart) assertFalse(expandableViewState.hidden) } + + @Test + fun maybeUpdateHeadsUpIsVisible_endVisible_true() { + val expandableViewState = ExpandableViewState() + expandableViewState.headsUpIsVisible = false + + stackScrollAlgorithm.maybeUpdateHeadsUpIsVisible(expandableViewState, + /* isShadeExpanded= */ true, + /* mustStayOnScreen= */ true, + /* isViewEndVisible= */ true, + /* viewEnd= */ 0f, + /* maxHunY= */ 10f) + + assertTrue(expandableViewState.headsUpIsVisible) + } + + @Test + fun maybeUpdateHeadsUpIsVisible_endHidden_false() { + val expandableViewState = ExpandableViewState() + expandableViewState.headsUpIsVisible = true + + stackScrollAlgorithm.maybeUpdateHeadsUpIsVisible(expandableViewState, + /* isShadeExpanded= */ true, + /* mustStayOnScreen= */ true, + /* isViewEndVisible= */ true, + /* viewEnd= */ 10f, + /* maxHunY= */ 0f) + + assertFalse(expandableViewState.headsUpIsVisible) + } + + @Test + fun maybeUpdateHeadsUpIsVisible_shadeClosed_noUpdate() { + val expandableViewState = ExpandableViewState() + expandableViewState.headsUpIsVisible = true + + stackScrollAlgorithm.maybeUpdateHeadsUpIsVisible(expandableViewState, + /* isShadeExpanded= */ false, + /* mustStayOnScreen= */ true, + /* isViewEndVisible= */ true, + /* viewEnd= */ 10f, + /* maxHunY= */ 1f) + + assertTrue(expandableViewState.headsUpIsVisible) + } + + @Test + fun maybeUpdateHeadsUpIsVisible_notHUN_noUpdate() { + val expandableViewState = ExpandableViewState() + expandableViewState.headsUpIsVisible = true + + stackScrollAlgorithm.maybeUpdateHeadsUpIsVisible(expandableViewState, + /* isShadeExpanded= */ true, + /* mustStayOnScreen= */ false, + /* isViewEndVisible= */ true, + /* viewEnd= */ 10f, + /* maxHunY= */ 1f) + + assertTrue(expandableViewState.headsUpIsVisible) + } + + @Test + fun maybeUpdateHeadsUpIsVisible_topHidden_noUpdate() { + val expandableViewState = ExpandableViewState() + expandableViewState.headsUpIsVisible = true + + stackScrollAlgorithm.maybeUpdateHeadsUpIsVisible(expandableViewState, + /* isShadeExpanded= */ true, + /* mustStayOnScreen= */ true, + /* isViewEndVisible= */ false, + /* viewEnd= */ 10f, + /* maxHunY= */ 1f) + + assertTrue(expandableViewState.headsUpIsVisible) + } + + @Test + fun clampHunToTop_viewYGreaterThanQqs_viewYUnchanged() { + val expandableViewState = ExpandableViewState() + expandableViewState.yTranslation = 50f + + stackScrollAlgorithm.clampHunToTop(/* quickQsOffsetHeight= */ 10f, + /* stackTranslation= */ 0f, + /* collapsedHeight= */ 1f, expandableViewState) + + // qqs (10 + 0) < viewY (50) + assertEquals(50f, expandableViewState.yTranslation) + } + + @Test + fun clampHunToTop_viewYLessThanQqs_viewYChanged() { + val expandableViewState = ExpandableViewState() + expandableViewState.yTranslation = -10f + + stackScrollAlgorithm.clampHunToTop(/* quickQsOffsetHeight= */ 10f, + /* stackTranslation= */ 0f, + /* collapsedHeight= */ 1f, expandableViewState) + + // qqs (10 + 0) > viewY (-10) + assertEquals(10f, expandableViewState.yTranslation) + } + + + @Test + fun clampHunToTop_viewYFarAboveVisibleStack_heightCollapsed() { + val expandableViewState = ExpandableViewState() + expandableViewState.height = 20 + expandableViewState.yTranslation = -100f + + stackScrollAlgorithm.clampHunToTop(/* quickQsOffsetHeight= */ 10f, + /* stackTranslation= */ 0f, + /* collapsedHeight= */ 10f, expandableViewState) + + // newTranslation = max(10, -100) = 10 + // distToRealY = 10 - (-100f) = 110 + // height = max(20 - 110, 10f) + assertEquals(10, expandableViewState.height) + } + + @Test + fun clampHunToTop_viewYNearVisibleStack_heightTallerThanCollapsed() { + val expandableViewState = ExpandableViewState() + expandableViewState.height = 20 + expandableViewState.yTranslation = 5f + + stackScrollAlgorithm.clampHunToTop(/* quickQsOffsetHeight= */ 10f, + /* stackTranslation= */ 0f, + /* collapsedHeight= */ 10f, expandableViewState) + + // newTranslation = max(10, 5) = 10 + // distToRealY = 10 - 5 = 5 + // height = max(20 - 5, 10) = 15 + assertEquals(15, expandableViewState.height) + } + + @Test + fun computeCornerRoundnessForPinnedHun_stackBelowScreen_round() { + val currentRoundness = stackScrollAlgorithm.computeCornerRoundnessForPinnedHun( + /* hostViewHeight= */ 100f, + /* stackY= */ 110f, + /* viewMaxHeight= */ 20f, + /* originalCornerRoundness= */ 0f) + assertEquals(1f, currentRoundness) + } + + @Test + fun computeCornerRoundnessForPinnedHun_stackAboveScreenBelowPinPoint_halfRound() { + val currentRoundness = stackScrollAlgorithm.computeCornerRoundnessForPinnedHun( + /* hostViewHeight= */ 100f, + /* stackY= */ 90f, + /* viewMaxHeight= */ 20f, + /* originalCornerRoundness= */ 0f) + assertEquals(0.5f, currentRoundness) + } + + @Test + fun computeCornerRoundnessForPinnedHun_stackAbovePinPoint_notRound() { + val currentRoundness = stackScrollAlgorithm.computeCornerRoundnessForPinnedHun( + /* hostViewHeight= */ 100f, + /* stackY= */ 0f, + /* viewMaxHeight= */ 20f, + /* originalCornerRoundness= */ 0f) + assertEquals(0f, currentRoundness) + } + + @Test + fun computeCornerRoundnessForPinnedHun_originallyRoundAndStackAbovePinPoint_round() { + val currentRoundness = stackScrollAlgorithm.computeCornerRoundnessForPinnedHun( + /* hostViewHeight= */ 100f, + /* stackY= */ 0f, + /* viewMaxHeight= */ 20f, + /* originalCornerRoundness= */ 1f) + assertEquals(1f, currentRoundness) + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java index e5b6286fcd7c..272ef3ddc64e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java @@ -131,6 +131,7 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase { when(mKeyguardBypassController.onBiometricAuthenticated(any(), anyBoolean())) .thenReturn(true); when(mAuthController.isUdfpsFingerDown()).thenReturn(false); + when(mVibratorHelper.hasVibrator()).thenReturn(true); mDependency.injectTestDependency(NotificationMediaManager.class, mMediaManager); mBiometricUnlockController = new BiometricUnlockController(mDozeScrimController, mKeyguardViewMediator, mScrimController, mShadeController, @@ -423,4 +424,35 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase { verify(mHandler).post(captor.capture()); captor.getValue().run(); } + + @Test + public void onFPFailureNoHaptics_notDeviceInteractive_showBouncer() { + // GIVEN no vibrator and the screen is off + when(mVibratorHelper.hasVibrator()).thenReturn(false); + when(mUpdateMonitor.isDeviceInteractive()).thenReturn(false); + when(mUpdateMonitor.isDreaming()).thenReturn(false); + + // WHEN FP fails + mBiometricUnlockController.onBiometricAuthFailed(BiometricSourceType.FINGERPRINT); + + // after device is finished waking up + mBiometricUnlockController.mWakefulnessObserver.onFinishedWakingUp(); + + // THEN show the bouncer + verify(mStatusBarKeyguardViewManager).showBouncer(true); + } + + @Test + public void onFPFailureNoHaptics_dreaming_showBouncer() { + // GIVEN no vibrator and device is dreaming + when(mVibratorHelper.hasVibrator()).thenReturn(false); + when(mUpdateMonitor.isDeviceInteractive()).thenReturn(true); + when(mUpdateMonitor.isDreaming()).thenReturn(true); + + // WHEN FP fails + mBiometricUnlockController.onBiometricAuthFailed(BiometricSourceType.FINGERPRINT); + + // THEN show the bouncer + verify(mStatusBarKeyguardViewManager).showBouncer(true); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java index 2faff0ced70a..b4532c431415 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java @@ -84,6 +84,7 @@ import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenu import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.assist.AssistManager; import com.android.systemui.broadcast.BroadcastDispatcher; +import com.android.systemui.charging.WiredChargingRippleController; import com.android.systemui.classifier.FalsingCollectorFake; import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.colorextraction.SysuiColorExtractor; @@ -117,7 +118,6 @@ import com.android.systemui.statusbar.OperatorNameViewController; import com.android.systemui.statusbar.PulseExpansionHandler; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.StatusBarStateControllerImpl; -import com.android.systemui.statusbar.charging.WiredChargingRippleController; import com.android.systemui.statusbar.connectivity.NetworkController; import com.android.systemui.statusbar.notification.DynamicPrivacyController; import com.android.systemui.statusbar.notification.NotifPipelineFlags; @@ -322,10 +322,8 @@ public class CentralSurfacesImplTest extends SysuiTestCase { NotificationLogger notificationLogger = new NotificationLogger( mNotificationListener, mUiBgExecutor, - mNotifPipelineFlags, mNotifLiveDataStore, mVisibilityProvider, - mock(NotificationEntryManager.class), mock(NotifPipeline.class), mStatusBarStateController, mExpansionStateLogger, @@ -848,7 +846,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase { mCentralSurfaces.showKeyguardImpl(); // Starting a pulse should change the scrim controller to the pulsing state - when(mNotificationPanelViewController.isLaunchTransitionRunning()).thenReturn(true); when(mNotificationPanelViewController.isLaunchingAffordanceWithPreview()).thenReturn(true); mCentralSurfaces.updateScrimController(); verify(mScrimController).transitionTo(eq(ScrimState.UNLOCKED), any()); @@ -885,7 +882,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase { mCentralSurfaces.showKeyguardImpl(); // Starting a pulse should change the scrim controller to the pulsing state - when(mNotificationPanelViewController.isLaunchTransitionRunning()).thenReturn(true); when(mNotificationPanelViewController.isLaunchingAffordanceWithPreview()).thenReturn(false); mCentralSurfaces.updateScrimController(); verify(mScrimController).transitionTo(eq(ScrimState.KEYGUARD)); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaTest.kt index 31465f45af42..4b557dc423ff 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaTest.kt @@ -12,12 +12,12 @@ import com.android.systemui.statusbar.policy.AccessibilityController import com.android.systemui.statusbar.policy.FlashlightController import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.tuner.TunerService +import java.util.concurrent.Executor import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.MockitoAnnotations -import java.util.concurrent.Executor @SmallTest @RunWith(AndroidTestingRunner::class) @@ -51,6 +51,5 @@ class KeyguardBottomAreaTest : SysuiTestCase() { null, false) as KeyguardBottomAreaView other.initFrom(mKeyguardBottomArea) - other.launchVoiceAssist() } -}
\ No newline at end of file +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightsOutNotifControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightsOutNotifControllerTest.java index 9664035e1e1b..fca9771648ea 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightsOutNotifControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightsOutNotifControllerTest.java @@ -108,7 +108,8 @@ public class LightsOutNotifControllerTest extends SysuiTestCase { false /* navbarColorManagedByIme */, BEHAVIOR_DEFAULT, null /* requestedVisibilities */, - null /* packageName */); + null /* packageName */, + null /* letterboxDetails */); assertTrue(mLightsOutNotifController.areLightsOut()); } @@ -121,7 +122,8 @@ public class LightsOutNotifControllerTest extends SysuiTestCase { false /* navbarColorManagedByIme */, BEHAVIOR_DEFAULT, null /* requestedVisibilities */, - null /* packageName */); + null /* packageName */, + null /* letterboxDetails */); assertFalse(mLightsOutNotifController.areLightsOut()); } @@ -152,7 +154,8 @@ public class LightsOutNotifControllerTest extends SysuiTestCase { false /* navbarColorManagedByIme */, BEHAVIOR_DEFAULT, null /* requestedVisibilities */, - null /* packageName */); + null /* packageName */, + null /* letterboxDetails */); // THEN we should show dot assertTrue(mLightsOutNotifController.shouldShowDot()); @@ -172,7 +175,8 @@ public class LightsOutNotifControllerTest extends SysuiTestCase { false /* navbarColorManagedByIme */, BEHAVIOR_DEFAULT, null /* requestedVisibilities */, - null /* packageName */); + null /* packageName */, + null /* letterboxDetails */); // THEN we shouldn't show the dot assertFalse(mLightsOutNotifController.shouldShowDot()); @@ -192,7 +196,8 @@ public class LightsOutNotifControllerTest extends SysuiTestCase { false /* navbarColorManagedByIme */, BEHAVIOR_DEFAULT, null /* requestedVisibilities */, - null /* packageName */); + null /* packageName */, + null /* letterboxDetails */); // THEN we shouldn't show the dot assertFalse(mLightsOutNotifController.shouldShowDot()); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java index 823a986af5a9..7fd61cfecfac 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java @@ -87,6 +87,7 @@ import com.android.systemui.DejankUtils; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.biometrics.AuthController; +import com.android.systemui.camera.CameraGestureHelper; import com.android.systemui.classifier.FalsingCollectorFake; import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.controls.dagger.ControlsComponent; @@ -106,7 +107,6 @@ import com.android.systemui.plugins.qs.QS; import com.android.systemui.qrcodescanner.controller.QRCodeScannerController; import com.android.systemui.screenrecord.RecordingController; import com.android.systemui.statusbar.CommandQueue; -import com.android.systemui.statusbar.KeyguardAffordanceView; import com.android.systemui.statusbar.KeyguardIndicationController; import com.android.systemui.statusbar.LockscreenShadeTransitionController; import com.android.systemui.statusbar.NotificationRemoteInputManager; @@ -404,8 +404,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { .thenReturn(mHeadsUpCallback); when(mKeyguardBottomAreaViewController.getView()).thenReturn(mKeyguardBottomArea); when(mView.findViewById(R.id.keyguard_bottom_area)).thenReturn(mKeyguardBottomArea); - when(mKeyguardBottomArea.getLeftView()).thenReturn(mock(KeyguardAffordanceView.class)); - when(mKeyguardBottomArea.getRightView()).thenReturn(mock(KeyguardAffordanceView.class)); when(mKeyguardBottomArea.animate()).thenReturn(mock(ViewPropertyAnimator.class)); when(mView.findViewById(R.id.qs_frame)).thenReturn(mQsFrame); when(mView.findViewById(R.id.keyguard_status_view)) @@ -549,7 +547,8 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { mNotificationStackSizeCalculator, mUnlockedScreenOffAnimationController, mShadeTransitionController, - mSystemClock); + mSystemClock, + mock(CameraGestureHelper.class)); mNotificationPanelViewController.initDependencies( mCentralSurfaces, () -> {}, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt index e0bf9e7b0081..1af8a77b1610 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt @@ -44,6 +44,7 @@ import com.android.systemui.GuestResumeSessionReceiver import com.android.systemui.GuestSessionNotification import com.android.systemui.R import com.android.systemui.SysuiTestCase +import com.android.systemui.animation.DialogCuj import com.android.systemui.animation.DialogLaunchAnimator import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.broadcast.BroadcastSender @@ -72,12 +73,12 @@ import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mock -import org.mockito.Mockito.`when` import org.mockito.Mockito.doNothing import org.mockito.Mockito.doReturn import org.mockito.Mockito.eq import org.mockito.Mockito.mock import org.mockito.Mockito.verify +import org.mockito.Mockito.`when` import org.mockito.MockitoAnnotations @RunWith(AndroidTestingRunner::class) @@ -362,7 +363,10 @@ class UserSwitcherControllerTest : SysuiTestCase() { userSwitcherController.onUserListItemClicked(currentGuestUserRecord, dialogShower) assertNotNull(userSwitcherController.mExitGuestDialog) testableLooper.processAllMessages() - verify(dialogShower).showDialog(userSwitcherController.mExitGuestDialog) + verify(dialogShower) + .showDialog( + userSwitcherController.mExitGuestDialog, + DialogCuj(InteractionJankMonitor.CUJ_USER_DIALOG_OPEN, "exit_guest_mode")) } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/service/ObservableServiceConnectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/service/ObservableServiceConnectionTest.java index 22d7273dcd20..046ad1293521 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/util/service/ObservableServiceConnectionTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/util/service/ObservableServiceConnectionTest.java @@ -145,4 +145,28 @@ public class ObservableServiceConnectionTest extends SysuiTestCase { connection.unbind(); verify(mContext, never()).unbindService(eq(connection)); } + + @Test + public void testUnbind() { + ObservableServiceConnection<Foo> connection = new ObservableServiceConnection<>(mContext, + mIntent, mExecutor, mTransformer); + connection.addCallback(mCallback); + connection.onServiceDisconnected(mComponentName); + + // Disconnects before binds should be ignored. + verify(mCallback, never()).onDisconnected(eq(connection), anyInt()); + + when(mContext.bindService(eq(mIntent), anyInt(), eq(mExecutor), eq(connection))) + .thenReturn(true); + connection.bind(); + + mExecutor.runAllReady(); + + connection.unbind(); + + mExecutor.runAllReady(); + + verify(mCallback).onDisconnected(eq(connection), + eq(ObservableServiceConnection.DISCONNECT_REASON_UNBIND)); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/service/PersistentConnectionManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/service/PersistentConnectionManagerTest.java index 53d4a96b0640..db0139c9b0d1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/util/service/PersistentConnectionManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/util/service/PersistentConnectionManagerTest.java @@ -16,6 +16,7 @@ package com.android.systemui.util.service; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import android.testing.AndroidTestingRunner; @@ -120,6 +121,24 @@ public class PersistentConnectionManagerTest extends SysuiTestCase { } /** + * Ensures manual unbind does not reconnect. + */ + @Test + public void testStopDoesNotReconnect() { + mConnectionManager.start(); + ArgumentCaptor<ObservableServiceConnection.Callback<Proxy>> connectionCallbackCaptor = + ArgumentCaptor.forClass(ObservableServiceConnection.Callback.class); + + verify(mConnection).addCallback(connectionCallbackCaptor.capture()); + verify(mConnection).bind(); + Mockito.clearInvocations(mConnection); + mConnectionManager.stop(); + mFakeExecutor.advanceClockToNext(); + mFakeExecutor.runAllReady(); + verify(mConnection, never()).bind(); + } + + /** * Ensures rebind on package change. */ @Test diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java index 9b29bae1fc46..b34482f0964f 100644 --- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java +++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java @@ -2300,9 +2300,9 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ int processId, long threadId, int callingUid, Bundle callingStack) { if (mTrace.isA11yTracingEnabledForTypes(loggingTypes)) { ArrayList<StackTraceElement> list = - (ArrayList<StackTraceElement>) callingStack.getSerializable(CALL_STACK); + (ArrayList<StackTraceElement>) callingStack.getSerializable(CALL_STACK, java.util.ArrayList.class); HashSet<String> ignoreList = - (HashSet<String>) callingStack.getSerializable(IGNORE_CALL_STACK); + (HashSet<String>) callingStack.getSerializable(IGNORE_CALL_STACK, java.util.HashSet.class); mTrace.logTrace(timestamp, where, loggingTypes, callingParams, processId, threadId, callingUid, list.toArray(new StackTraceElement[list.size()]), ignoreList); } diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 99c849527034..79f590f8384a 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -199,9 +199,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub private static final String FUNCTION_REGISTER_UI_TEST_AUTOMATION_SERVICE = "registerUiTestAutomationService"; - private static final String TEMPORARY_ENABLE_ACCESSIBILITY_UNTIL_KEYGUARD_REMOVED = - "temporaryEnableAccessibilityStateUntilKeyguardRemoved"; - private static final String GET_WINDOW_TOKEN = "getWindowToken"; private static final String SET_PIP_ACTION_REPLACEMENT = @@ -1235,46 +1232,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } @Override - public void temporaryEnableAccessibilityStateUntilKeyguardRemoved( - ComponentName service, boolean touchExplorationEnabled) { - if (mTraceManager.isA11yTracingEnabledForTypes(FLAGS_ACCESSIBILITY_MANAGER)) { - mTraceManager.logTrace( - LOG_TAG + ".temporaryEnableAccessibilityStateUntilKeyguardRemoved", - FLAGS_ACCESSIBILITY_MANAGER, - "service=" + service + ";touchExplorationEnabled=" + touchExplorationEnabled); - } - - mSecurityPolicy.enforceCallingPermission( - Manifest.permission.TEMPORARY_ENABLE_ACCESSIBILITY, - TEMPORARY_ENABLE_ACCESSIBILITY_UNTIL_KEYGUARD_REMOVED); - if (mTraceManager.isA11yTracingEnabledForTypes(FLAGS_WINDOW_MANAGER_INTERNAL)) { - mTraceManager.logTrace("WindowManagerInternal.isKeyguardLocked", - FLAGS_WINDOW_MANAGER_INTERNAL); - } - if (!mWindowManagerService.isKeyguardLocked()) { - return; - } - synchronized (mLock) { - // Set the temporary state. - AccessibilityUserState userState = getCurrentUserStateLocked(); - - userState.setTouchExplorationEnabledLocked(touchExplorationEnabled); - userState.setDisplayMagnificationEnabledLocked(false); - userState.disableShortcutMagnificationLocked(); - userState.setAutoclickEnabledLocked(false); - userState.mEnabledServices.clear(); - userState.mEnabledServices.add(service); - userState.getBindingServicesLocked().clear(); - userState.getCrashedServicesLocked().clear(); - userState.mTouchExplorationGrantedServices.clear(); - userState.mTouchExplorationGrantedServices.add(service); - - // User the current state instead settings. - onUserStateChangedLocked(userState); - } - } - - @Override public IBinder getWindowToken(int windowId, int userId) { if (mTraceManager.isA11yTracingEnabledForTypes(FLAGS_ACCESSIBILITY_MANAGER)) { mTraceManager.logTrace(LOG_TAG + ".getWindowToken", diff --git a/services/accessibility/java/com/android/server/accessibility/PolicyWarningUIController.java b/services/accessibility/java/com/android/server/accessibility/PolicyWarningUIController.java index af816451dca2..7fd859ca9333 100644 --- a/services/accessibility/java/com/android/server/accessibility/PolicyWarningUIController.java +++ b/services/accessibility/java/com/android/server/accessibility/PolicyWarningUIController.java @@ -227,7 +227,7 @@ public class PolicyWarningUIController { public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); final ComponentName componentName = intent.getParcelableExtra( - Intent.EXTRA_COMPONENT_NAME); + Intent.EXTRA_COMPONENT_NAME, android.content.ComponentName.class); if (TextUtils.isEmpty(action) || componentName == null) { return; } diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java index 966d887d11f7..dc39b01cf6b6 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java @@ -184,7 +184,12 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH mPanningScalingState.mScrollGestureDetector.onTouchEvent(event); mPanningScalingState.mScaleGestureDetector.onTouchEvent(event); - stateHandler.onMotionEvent(event, rawEvent, policyFlags); + try { + stateHandler.onMotionEvent(event, rawEvent, policyFlags); + } catch (GestureException e) { + Slog.e(mLogTag, "Error processing motion event", e); + clearAndTransitionToStateDetecting(); + } } @Override @@ -281,7 +286,8 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH } interface State { - void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags); + void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) + throws GestureException; default void clear() {} @@ -439,7 +445,8 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH private boolean mLastMoveOutsideMagnifiedRegion; @Override - public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) { + public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) + throws GestureException { final int action = event.getActionMasked(); switch (action) { case ACTION_POINTER_DOWN: { @@ -449,7 +456,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH break; case ACTION_MOVE: { if (event.getPointerCount() != 1) { - throw new IllegalStateException("Should have one pointer down."); + throw new GestureException("Should have one pointer down."); } final float eventX = event.getX(); final float eventY = event.getY(); @@ -475,7 +482,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH case ACTION_DOWN: case ACTION_POINTER_UP: { - throw new IllegalArgumentException( + throw new GestureException( "Unexpected event type: " + MotionEvent.actionToString(action)); } } @@ -1087,4 +1094,13 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH mGestureHandler.mDetectingState.setShortcutTriggered(false); } } + + /** + * Indicates an error with a gesture handler or state. + */ + private static class GestureException extends Exception { + GestureException(String message) { + super(message); + } + } } diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java index 1eaa59a0871a..b09cb00f5eed 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java @@ -251,7 +251,7 @@ public final class AutofillManagerServiceShellCommand extends ShellCommand { final CountDownLatch latch = new CountDownLatch(1); mService.calculateScore(algorithm, value1, value2, new RemoteCallback((result) -> { - final Scores scores = result.getParcelable(EXTRA_SCORES); + final Scores scores = result.getParcelable(EXTRA_SCORES, android.service.autofill.AutofillFieldClassificationService.Scores.class); if (scores == null) { pw.println("no score"); } else { diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index 9f9846117a29..1fea539fa016 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -395,7 +395,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState Slog.v(TAG, "mDelayedFillBroadcastReceiver delayed fill action received"); synchronized (mLock) { int requestId = intent.getIntExtra(EXTRA_REQUEST_ID, 0); - FillResponse response = intent.getParcelableExtra(EXTRA_FILL_RESPONSE); + FillResponse response = intent.getParcelableExtra(EXTRA_FILL_RESPONSE, android.service.autofill.FillResponse.class); mAssistReceiver.processDelayedFillLocked(requestId, response); } } @@ -559,7 +559,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState return; } - final AssistStructure structure = resultData.getParcelable(ASSIST_KEY_STRUCTURE); + final AssistStructure structure = resultData.getParcelable(ASSIST_KEY_STRUCTURE, android.app.assist.AssistStructure.class); if (structure == null) { Slog.e(TAG, "No assist structure - app might have crashed providing it"); return; @@ -1811,7 +1811,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState @GuardedBy("mLock") void setAuthenticationResultForAugmentedAutofillLocked(Bundle data, int authId) { final Dataset dataset = (data == null) ? null : - data.getParcelable(AutofillManager.EXTRA_AUTHENTICATION_RESULT); + data.getParcelable(AutofillManager.EXTRA_AUTHENTICATION_RESULT, android.service.autofill.Dataset.class); if (sDebug) { Slog.d(TAG, "Auth result for augmented autofill: sessionId=" + id + ", authId=" + authId + ", dataset=" + dataset); @@ -2251,7 +2251,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState logContextCommitted(null, null, saveDialogNotShowReason, commitReason); return; } - final Scores scores = result.getParcelable(EXTRA_SCORES); + final Scores scores = result.getParcelable(EXTRA_SCORES, android.service.autofill.AutofillFieldClassificationService.Scores.class); if (scores == null) { Slog.w(TAG, "No field classification score on " + result); return; diff --git a/services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java b/services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java index 5457ef9acaf7..b3314ede8e50 100644 --- a/services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java +++ b/services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java @@ -300,10 +300,10 @@ class AssociationRequestsProcessor { return; } - final AssociationRequest request = data.getParcelable(EXTRA_ASSOCIATION_REQUEST); + final AssociationRequest request = data.getParcelable(EXTRA_ASSOCIATION_REQUEST, android.companion.AssociationRequest.class); final IAssociationRequestCallback callback = IAssociationRequestCallback.Stub .asInterface(data.getBinder(EXTRA_APPLICATION_CALLBACK)); - final ResultReceiver resultReceiver = data.getParcelable(EXTRA_RESULT_RECEIVER); + final ResultReceiver resultReceiver = data.getParcelable(EXTRA_RESULT_RECEIVER, android.os.ResultReceiver.class); requireNonNull(request); requireNonNull(callback); @@ -313,7 +313,7 @@ class AssociationRequestsProcessor { if (request.isSelfManaged()) { macAddress = null; } else { - macAddress = data.getParcelable(EXTRA_MAC_ADDRESS); + macAddress = data.getParcelable(EXTRA_MAC_ADDRESS, android.net.MacAddress.class); requireNonNull(macAddress); } diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java index 41a759254909..7a95a8fe8c7f 100644 --- a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java +++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java @@ -446,8 +446,8 @@ final class ContentCapturePerUserService @NonNull Bundle data) { final int id = getSessionId(activityToken); final Bundle assistData = data.getBundle(ASSIST_KEY_DATA); - final AssistStructure assistStructure = data.getParcelable(ASSIST_KEY_STRUCTURE); - final AssistContent assistContent = data.getParcelable(ASSIST_KEY_CONTENT); + final AssistStructure assistStructure = data.getParcelable(ASSIST_KEY_STRUCTURE, android.app.assist.AssistStructure.class); + final AssistContent assistContent = data.getParcelable(ASSIST_KEY_CONTENT, android.app.assist.AssistContent.class); final SnapshotData snapshotData = new SnapshotData(assistData, assistStructure, assistContent); if (id != NO_SESSION_ID) { diff --git a/services/core/java/com/android/server/ExplicitHealthCheckController.java b/services/core/java/com/android/server/ExplicitHealthCheckController.java index 77059d918052..20de40e73130 100644 --- a/services/core/java/com/android/server/ExplicitHealthCheckController.java +++ b/services/core/java/com/android/server/ExplicitHealthCheckController.java @@ -246,7 +246,7 @@ class ExplicitHealthCheckController { try { mRemoteService.getSupportedPackages(new RemoteCallback(result -> { List<PackageConfig> packages = - result.getParcelableArrayList(EXTRA_SUPPORTED_PACKAGES); + result.getParcelableArrayList(EXTRA_SUPPORTED_PACKAGES, android.service.watchdog.ExplicitHealthCheckService.PackageConfig.class); Slog.i(TAG, "Explicit health check supported packages " + packages); consumer.accept(packages); })); diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index 6b731c319c4b..eb0f3f00d291 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -3090,7 +3090,7 @@ public class AccountManagerService } } - Intent intent = result.getParcelable(AccountManager.KEY_INTENT); + Intent intent = result.getParcelable(AccountManager.KEY_INTENT, android.content.Intent.class); if (intent != null && notifyOnAuthFailure && !customTokens) { /* * Make sure that the supplied intent is owned by the authenticator @@ -3516,7 +3516,7 @@ public class AccountManagerService mNumResults++; Intent intent = null; if (result != null - && (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) { + && (intent = result.getParcelable(AccountManager.KEY_INTENT, android.content.Intent.class)) != null) { if (!checkKeyIntent( Binder.getCallingUid(), intent)) { @@ -5048,7 +5048,7 @@ public class AccountManagerService } } if (result != null - && (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) { + && (intent = result.getParcelable(AccountManager.KEY_INTENT, android.content.Intent.class)) != null) { if (!checkKeyIntent( Binder.getCallingUid(), intent)) { diff --git a/services/core/java/com/android/server/adb/AdbDebuggingManager.java b/services/core/java/com/android/server/adb/AdbDebuggingManager.java index 049f4bea6fa1..2eaf323ea370 100644 --- a/services/core/java/com/android/server/adb/AdbDebuggingManager.java +++ b/services/core/java/com/android/server/adb/AdbDebuggingManager.java @@ -649,7 +649,7 @@ public class AdbDebuggingManager { } else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) { // We only care about wifi type connections NetworkInfo networkInfo = (NetworkInfo) intent.getParcelableExtra( - WifiManager.EXTRA_NETWORK_INFO); + WifiManager.EXTRA_NETWORK_INFO, android.net.NetworkInfo.class); if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) { // Check for network disconnect if (!networkInfo.isConnected()) { diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java index 0e3823275777..73e4cf23c347 100644 --- a/services/core/java/com/android/server/audio/BtHelper.java +++ b/services/core/java/com/android/server/audio/BtHelper.java @@ -303,7 +303,7 @@ public class BtHelper { Log.i(TAG, "receiveBtEvent action: " + action + " mScoAudioState: " + mScoAudioState); if (action.equals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED)) { - BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE, android.bluetooth.BluetoothDevice.class); setBtScoActiveDevice(btDevice); } else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) { int btState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1); diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java index b425420479f0..66ef5e761194 100644 --- a/services/core/java/com/android/server/camera/CameraServiceProxy.java +++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java @@ -355,7 +355,7 @@ public class CameraServiceProxy extends SystemService case UsbManager.ACTION_USB_DEVICE_ATTACHED: case UsbManager.ACTION_USB_DEVICE_DETACHED: synchronized (mLock) { - UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); + UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE, android.hardware.usb.UsbDevice.class); if (device != null) { notifyUsbDeviceHotplugLocked(device, action.equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)); diff --git a/services/core/java/com/android/server/display/WifiDisplayController.java b/services/core/java/com/android/server/display/WifiDisplayController.java index a7e1a2876f81..5b204ad9c853 100644 --- a/services/core/java/com/android/server/display/WifiDisplayController.java +++ b/services/core/java/com/android/server/display/WifiDisplayController.java @@ -1090,7 +1090,7 @@ final class WifiDisplayController implements DumpUtils.Dump { handlePeersChanged(); } else if (action.equals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)) { NetworkInfo networkInfo = (NetworkInfo)intent.getParcelableExtra( - WifiP2pManager.EXTRA_NETWORK_INFO); + WifiP2pManager.EXTRA_NETWORK_INFO, android.net.NetworkInfo.class); if (DEBUG) { Slog.d(TAG, "Received WIFI_P2P_CONNECTION_CHANGED_ACTION: networkInfo=" + networkInfo); @@ -1099,7 +1099,7 @@ final class WifiDisplayController implements DumpUtils.Dump { handleConnectionChanged(networkInfo); } else if (action.equals(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION)) { mThisDevice = (WifiP2pDevice) intent.getParcelableExtra( - WifiP2pManager.EXTRA_WIFI_P2P_DEVICE); + WifiP2pManager.EXTRA_WIFI_P2P_DEVICE, android.net.wifi.p2p.WifiP2pDevice.class); if (DEBUG) { Slog.d(TAG, "Received WIFI_P2P_THIS_DEVICE_CHANGED_ACTION: mThisDevice= " + mThisDevice); diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index b45dc7ff0f6b..deea90f31e9e 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -173,7 +173,6 @@ import com.android.internal.inputmethod.StartInputReason; import com.android.internal.inputmethod.UnbindReason; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.notification.SystemNotificationChannels; -import com.android.internal.os.SomeArgs; import com.android.internal.os.TransferPipe; import com.android.internal.util.ConcurrentUtils; import com.android.internal.util.DumpUtils; @@ -2475,9 +2474,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub } @GuardedBy("ImfLock.class") - @Nullable - InputBindResult attachNewAccessibilityLocked(@StartInputReason int startInputReason, - boolean initial, int id) { + private void attachNewAccessibilityLocked(@StartInputReason int startInputReason, + boolean initial) { if (!mBoundToAccessibility) { AccessibilityManagerInternal.get().bindInput(); mBoundToAccessibility = true; @@ -2486,8 +2484,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub // TODO(b/187453053): grantImplicitAccess to accessibility services access? if so, need to // record accessibility services uid. - final AccessibilitySessionState accessibilitySession = - mCurClient.mAccessibilitySessions.get(id); // We don't start input when session for a11y is created. We start input when // input method start input, a11y manager service is always on. if (startInputReason != StartInputReason.SESSION_CREATED_BY_ACCESSIBILITY) { @@ -2495,19 +2491,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub AccessibilityManagerInternal.get().startInput(mCurRemoteAccessibilityInputConnection, mCurEditorInfo, !initial /* restarting */); } - - if (accessibilitySession != null) { - final SessionState session = mCurClient.curSession; - IInputMethodSession imeSession = session == null ? null : session.session; - final SparseArray<IAccessibilityInputMethodSession> accessibilityInputMethodSessions = - createAccessibilityInputMethodSessions(mCurClient.mAccessibilitySessions); - return new InputBindResult( - InputBindResult.ResultCode.SUCCESS_WITH_ACCESSIBILITY_SESSION, - imeSession, accessibilityInputMethodSessions, null, - getCurIdLocked(), getSequenceNumberLocked(), mCurVirtualDisplayToScreenMatrix, - false); - } - return null; } private SparseArray<IAccessibilityInputMethodSession> createAccessibilityInputMethodSessions( @@ -2617,7 +2600,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub // we can always attach to accessibility because AccessibilityManagerService is // always on. attachNewAccessibilityLocked(startInputReason, - (startInputFlags & StartInputFlags.INITIAL_CONNECTION) != 0, -1); + (startInputFlags & StartInputFlags.INITIAL_CONNECTION) != 0); return attachNewInputLocked(startInputReason, (startInputFlags & StartInputFlags.INITIAL_CONNECTION) != 0); } @@ -2796,8 +2779,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub method, session, channel); InputBindResult res = attachNewInputLocked( StartInputReason.SESSION_CREATED_BY_IME, true); - attachNewAccessibilityLocked(StartInputReason.SESSION_CREATED_BY_IME, - true, -1); + attachNewAccessibilityLocked(StartInputReason.SESSION_CREATED_BY_IME, true); if (res.method != null) { mCurClient.client.onBindMethod(res); } @@ -3429,7 +3411,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @Override public void reportPerceptibleAsync(IBinder windowToken, boolean perceptible) { Objects.requireNonNull(windowToken, "windowToken must not be null"); - int uid = Binder.getCallingUid(); synchronized (ImfLock.class) { if (!calledFromValidUserLocked()) { return; @@ -4711,7 +4692,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @UiThread @Override public boolean handleMessage(Message msg) { - SomeArgs args; switch (msg.what) { case MSG_SHOW_IM_SUBTYPE_PICKER: final boolean showAuxSubtypes; @@ -5449,9 +5429,21 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub mCurClient.mAccessibilitySessions.put(accessibilityConnectionId, new AccessibilitySessionState(mCurClient, accessibilityConnectionId, session)); - InputBindResult res = attachNewAccessibilityLocked( - StartInputReason.SESSION_CREATED_BY_ACCESSIBILITY, true, - accessibilityConnectionId); + + attachNewAccessibilityLocked(StartInputReason.SESSION_CREATED_BY_ACCESSIBILITY, + true); + + final SessionState sessionState = mCurClient.curSession; + final IInputMethodSession imeSession = sessionState == null + ? null : sessionState.session; + final SparseArray<IAccessibilityInputMethodSession> + accessibilityInputMethodSessions = + createAccessibilityInputMethodSessions( + mCurClient.mAccessibilitySessions); + final InputBindResult res = new InputBindResult( + InputBindResult.ResultCode.SUCCESS_WITH_ACCESSIBILITY_SESSION, + imeSession, accessibilityInputMethodSessions, null, getCurIdLocked(), + getSequenceNumberLocked(), mCurVirtualDisplayToScreenMatrix, false); mCurClient.client.onBindAccessibilityService(res, accessibilityConnectionId); } } diff --git a/services/core/java/com/android/server/locksettings/ResumeOnRebootServiceProvider.java b/services/core/java/com/android/server/locksettings/ResumeOnRebootServiceProvider.java index ec80521be2e5..70fdccdf2f7f 100644 --- a/services/core/java/com/android/server/locksettings/ResumeOnRebootServiceProvider.java +++ b/services/core/java/com/android/server/locksettings/ResumeOnRebootServiceProvider.java @@ -182,7 +182,7 @@ public class ResumeOnRebootServiceProvider { waitForLatch(binderLatch, "wrapSecret", timeOutInMillis); if (resultCallback.getResult().containsKey(ResumeOnRebootService.EXCEPTION_KEY)) { throwTypedException(resultCallback.getResult().getParcelable( - ResumeOnRebootService.EXCEPTION_KEY)); + ResumeOnRebootService.EXCEPTION_KEY, android.os.ParcelableException.class)); } return resultCallback.mResult.getByteArray(ResumeOnRebootService.WRAPPED_BLOB_KEY); } @@ -202,7 +202,7 @@ public class ResumeOnRebootServiceProvider { waitForLatch(binderLatch, "unWrapSecret", timeOut); if (resultCallback.getResult().containsKey(ResumeOnRebootService.EXCEPTION_KEY)) { throwTypedException(resultCallback.getResult().getParcelable( - ResumeOnRebootService.EXCEPTION_KEY)); + ResumeOnRebootService.EXCEPTION_KEY, android.os.ParcelableException.class)); } return resultCallback.getResult().getByteArray( ResumeOnRebootService.UNWRAPPED_BLOB_KEY); diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java index 3386408f32cc..c8f1cb29d826 100644 --- a/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java +++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java @@ -99,8 +99,8 @@ public class SyntheticPasswordCrypto { return outputStream.toByteArray(); } - public static byte[] encrypt(byte[] keyBytes, byte[] personalisation, byte[] message) { - byte[] keyHash = personalisedHash(personalisation, keyBytes); + public static byte[] encrypt(byte[] keyBytes, byte[] personalization, byte[] message) { + byte[] keyHash = personalizedHash(personalization, keyBytes); SecretKeySpec key = new SecretKeySpec(Arrays.copyOf(keyHash, AES_KEY_LENGTH), KeyProperties.KEY_ALGORITHM_AES); try { @@ -113,8 +113,8 @@ public class SyntheticPasswordCrypto { } } - public static byte[] decrypt(byte[] keyBytes, byte[] personalisation, byte[] ciphertext) { - byte[] keyHash = personalisedHash(personalisation, keyBytes); + public static byte[] decrypt(byte[] keyBytes, byte[] personalization, byte[] ciphertext) { + byte[] keyHash = personalizedHash(personalization, keyBytes); SecretKeySpec key = new SecretKeySpec(Arrays.copyOf(keyHash, AES_KEY_LENGTH), KeyProperties.KEY_ALGORITHM_AES); try { @@ -220,17 +220,17 @@ public class SyntheticPasswordCrypto { } } - protected static byte[] personalisedHash(byte[] personalisation, byte[]... message) { + protected static byte[] personalizedHash(byte[] personalization, byte[]... message) { try { final int PADDING_LENGTH = 128; MessageDigest digest = MessageDigest.getInstance("SHA-512"); - if (personalisation.length > PADDING_LENGTH) { - throw new IllegalArgumentException("Personalisation too long"); + if (personalization.length > PADDING_LENGTH) { + throw new IllegalArgumentException("Personalization too long"); } // Personalize the hash // Pad it to the block size of the hash function - personalisation = Arrays.copyOf(personalisation, PADDING_LENGTH); - digest.update(personalisation); + personalization = Arrays.copyOf(personalization, PADDING_LENGTH); + digest.update(personalization); for (byte[] data : message) { digest.update(data); } diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java index f5ee9068a623..f5151c4ace19 100644 --- a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java +++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java @@ -129,7 +129,7 @@ public class SyntheticPasswordManager { private static final int PASSWORD_TOKEN_LENGTH = 32; private static final String TAG = "SyntheticPasswordManager"; - private static final byte[] PERSONALISATION_SECDISCARDABLE = "secdiscardable-transform".getBytes(); + private static final byte[] PERSONALIZATION_SECDISCARDABLE = "secdiscardable-transform".getBytes(); private static final byte[] PERSONALIZATION_KEY_STORE_PASSWORD = "keystore-password".getBytes(); private static final byte[] PERSONALIZATION_USER_GK_AUTH = "user-gk-authentication".getBytes(); private static final byte[] PERSONALIZATION_SP_GK_AUTH = "sp-gk-authentication".getBytes(); @@ -138,11 +138,11 @@ public class SyntheticPasswordManager { private static final byte[] PERSONALIZATION_SP_SPLIT = "sp-split".getBytes(); private static final byte[] PERSONALIZATION_PASSWORD_HASH = "pw-hash".getBytes(); private static final byte[] PERSONALIZATION_E0 = "e0-encryption".getBytes(); - private static final byte[] PERSONALISATION_WEAVER_PASSWORD = "weaver-pwd".getBytes(); - private static final byte[] PERSONALISATION_WEAVER_KEY = "weaver-key".getBytes(); - private static final byte[] PERSONALISATION_WEAVER_TOKEN = "weaver-token".getBytes(); + private static final byte[] PERSONALIZATION_WEAVER_PASSWORD = "weaver-pwd".getBytes(); + private static final byte[] PERSONALIZATION_WEAVER_KEY = "weaver-key".getBytes(); + private static final byte[] PERSONALIZATION_WEAVER_TOKEN = "weaver-token".getBytes(); private static final byte[] PERSONALIZATION_PASSWORD_METRICS = "password-metrics".getBytes(); - private static final byte[] PERSONALISATION_CONTEXT = + private static final byte[] PERSONALIZATION_CONTEXT = "android-synthetic-password-personalization-context".getBytes(); static class AuthenticationResult { @@ -199,9 +199,9 @@ public class SyntheticPasswordManager { private byte[] deriveSubkey(byte[] personalization) { if (mVersion == SYNTHETIC_PASSWORD_VERSION_V3) { return (new SP800Derive(mSyntheticPassword)) - .withContext(personalization, PERSONALISATION_CONTEXT); + .withContext(personalization, PERSONALIZATION_CONTEXT); } else { - return SyntheticPasswordCrypto.personalisedHash(personalization, + return SyntheticPasswordCrypto.personalizedHash(personalization, mSyntheticPassword); } } @@ -278,7 +278,7 @@ public class SyntheticPasswordManager { * AuthenticationToken.mSyntheticPassword for details on what each block means. */ private void recreate(byte[] escrowSplit0, byte[] escrowSplit1) { - mSyntheticPassword = bytesToHex(SyntheticPasswordCrypto.personalisedHash( + mSyntheticPassword = bytesToHex(SyntheticPasswordCrypto.personalizedHash( PERSONALIZATION_SP_SPLIT, escrowSplit0, escrowSplit1)); } @@ -920,7 +920,7 @@ public class SyntheticPasswordManager { if (isWeaverAvailable()) { tokenData.weaverSecret = secureRandom(mWeaverConfig.valueSize); tokenData.secdiscardableOnDisk = SyntheticPasswordCrypto.encrypt(tokenData.weaverSecret, - PERSONALISATION_WEAVER_TOKEN, secdiscardable); + PERSONALIZATION_WEAVER_TOKEN, secdiscardable); } else { tokenData.secdiscardableOnDisk = secdiscardable; tokenData.weaverSecret = null; @@ -1163,7 +1163,7 @@ public class SyntheticPasswordManager { return result; } secdiscardable = SyntheticPasswordCrypto.decrypt(response.getGatekeeperHAT(), - PERSONALISATION_WEAVER_TOKEN, secdiscardable); + PERSONALIZATION_WEAVER_TOKEN, secdiscardable); } byte[] applicationId = transformUnderSecdiscardable(token, secdiscardable); result.authToken = unwrapSyntheticPasswordBlob(handle, type, applicationId, 0L, userId); @@ -1329,8 +1329,8 @@ public class SyntheticPasswordManager { } private byte[] transformUnderWeaverSecret(byte[] data, byte[] secret) { - byte[] weaverSecret = SyntheticPasswordCrypto.personalisedHash( - PERSONALISATION_WEAVER_PASSWORD, secret); + byte[] weaverSecret = SyntheticPasswordCrypto.personalizedHash( + PERSONALIZATION_WEAVER_PASSWORD, secret); byte[] result = new byte[data.length + weaverSecret.length]; System.arraycopy(data, 0, result, 0, data.length); System.arraycopy(weaverSecret, 0, result, data.length, weaverSecret.length); @@ -1338,8 +1338,8 @@ public class SyntheticPasswordManager { } private byte[] transformUnderSecdiscardable(byte[] data, byte[] rawSecdiscardable) { - byte[] secdiscardable = SyntheticPasswordCrypto.personalisedHash( - PERSONALISATION_SECDISCARDABLE, rawSecdiscardable); + byte[] secdiscardable = SyntheticPasswordCrypto.personalizedHash( + PERSONALIZATION_SECDISCARDABLE, rawSecdiscardable); byte[] result = new byte[data.length + secdiscardable.length]; System.arraycopy(data, 0, result, 0, data.length); System.arraycopy(secdiscardable, 0, result, data.length, secdiscardable.length); @@ -1459,11 +1459,11 @@ public class SyntheticPasswordManager { } private byte[] passwordTokenToGkInput(byte[] token) { - return SyntheticPasswordCrypto.personalisedHash(PERSONALIZATION_USER_GK_AUTH, token); + return SyntheticPasswordCrypto.personalizedHash(PERSONALIZATION_USER_GK_AUTH, token); } private byte[] passwordTokenToWeaverKey(byte[] token) { - byte[] key = SyntheticPasswordCrypto.personalisedHash(PERSONALISATION_WEAVER_KEY, token); + byte[] key = SyntheticPasswordCrypto.personalizedHash(PERSONALIZATION_WEAVER_KEY, token); if (key.length < mWeaverConfig.keySize) { throw new IllegalArgumentException("weaver key length too small"); } diff --git a/services/core/java/com/android/server/media/BluetoothRouteProvider.java b/services/core/java/com/android/server/media/BluetoothRouteProvider.java index d4d3a39c724e..e1a990d0f6bd 100644 --- a/services/core/java/com/android/server/media/BluetoothRouteProvider.java +++ b/services/core/java/com/android/server/media/BluetoothRouteProvider.java @@ -500,7 +500,7 @@ class BluetoothRouteProvider { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); - BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE, android.bluetooth.BluetoothDevice.class); BluetoothEventReceiver receiver = mEventReceiverMap.get(action); if (receiver != null) { diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java index e61f55381b0c..82dfd3ae178b 100644 --- a/services/core/java/com/android/server/media/MediaRouterService.java +++ b/services/core/java/com/android/server/media/MediaRouterService.java @@ -956,7 +956,7 @@ public final class MediaRouterService extends IMediaRouterService.Stub @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED)) { - BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE, android.bluetooth.BluetoothDevice.class); synchronized (mLock) { mActiveBluetoothDevice = btDevice; mGlobalBluetoothA2dpOn = btDevice != null; diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 1ea949ede03d..f2a12b468fef 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -1299,7 +1299,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // on background handler thread, and verified MANAGE_NETWORK_POLICY // permission above. - final NetworkTemplate template = intent.getParcelableExtra(EXTRA_NETWORK_TEMPLATE); + final NetworkTemplate template = intent.getParcelableExtra(EXTRA_NETWORK_TEMPLATE, android.net.NetworkTemplate.class); if (ACTION_SNOOZE_WARNING.equals(intent.getAction())) { performSnooze(template, TYPE_WARNING); } else if (ACTION_SNOOZE_RAPID.equals(intent.getAction())) { diff --git a/services/core/java/com/android/server/notification/CountdownConditionProvider.java b/services/core/java/com/android/server/notification/CountdownConditionProvider.java index 4b70e2e31888..efca5986e35a 100644 --- a/services/core/java/com/android/server/notification/CountdownConditionProvider.java +++ b/services/core/java/com/android/server/notification/CountdownConditionProvider.java @@ -155,7 +155,7 @@ public class CountdownConditionProvider extends SystemConditionProviderService { @Override public void onReceive(Context context, Intent intent) { if (ACTION.equals(intent.getAction())) { - final Uri conditionId = intent.getParcelableExtra(EXTRA_CONDITION_ID); + final Uri conditionId = intent.getParcelableExtra(EXTRA_CONDITION_ID, android.net.Uri.class); final boolean alarm = ZenModeConfig.isValidCountdownToAlarmConditionId(conditionId); final long time = ZenModeConfig.tryParseCountdownConditionId(conditionId); if (DEBUG) Slog.d(TAG, "Countdown condition fired: " + conditionId); diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java index cbaf485c077f..6dd0daa77ac6 100644 --- a/services/core/java/com/android/server/notification/NotificationRecord.java +++ b/services/core/java/com/android/server/notification/NotificationRecord.java @@ -682,7 +682,7 @@ public final class NotificationRecord { if (signals.containsKey(Adjustment.KEY_SNOOZE_CRITERIA)) { final ArrayList<SnoozeCriterion> snoozeCriterionList = adjustment.getSignals().getParcelableArrayList( - Adjustment.KEY_SNOOZE_CRITERIA); + Adjustment.KEY_SNOOZE_CRITERIA, android.service.notification.SnoozeCriterion.class); setSnoozeCriteria(snoozeCriterionList); EventLogTags.writeNotificationAdjusted(getKey(), Adjustment.KEY_SNOOZE_CRITERIA, snoozeCriterionList.toString()); @@ -708,7 +708,7 @@ public final class NotificationRecord { } if (signals.containsKey(Adjustment.KEY_CONTEXTUAL_ACTIONS)) { setSystemGeneratedSmartActions( - signals.getParcelableArrayList(Adjustment.KEY_CONTEXTUAL_ACTIONS)); + signals.getParcelableArrayList(Adjustment.KEY_CONTEXTUAL_ACTIONS, android.app.Notification.Action.class)); EventLogTags.writeNotificationAdjusted(getKey(), Adjustment.KEY_CONTEXTUAL_ACTIONS, getSystemGeneratedSmartActions().toString()); diff --git a/services/core/java/com/android/server/notification/NotificationRecordLogger.java b/services/core/java/com/android/server/notification/NotificationRecordLogger.java index 9a89efabc689..2789bcff0f68 100644 --- a/services/core/java/com/android/server/notification/NotificationRecordLogger.java +++ b/services/core/java/com/android/server/notification/NotificationRecordLogger.java @@ -399,7 +399,7 @@ public interface NotificationRecordLogger { private int getNumPeople(@Nullable Bundle extras) { if (extras != null) { ArrayList<Person> people = extras.getParcelableArrayList( - Notification.EXTRA_PEOPLE_LIST); + Notification.EXTRA_PEOPLE_LIST, android.app.Person.class); if (people != null && !people.isEmpty()) { return people.size(); } diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java index 0ba8d2c87e99..715967369ffb 100644 --- a/services/core/java/com/android/server/om/OverlayManagerService.java +++ b/services/core/java/com/android/server/om/OverlayManagerService.java @@ -942,7 +942,7 @@ public final class OverlayManagerService extends SystemService { final FabricatedOverlayInternal fabricated = request.extras.getParcelable( OverlayManagerTransaction.Request.BUNDLE_FABRICATED_OVERLAY - ); + , android.os.FabricatedOverlayInternal.class); Objects.requireNonNull(fabricated, "no fabricated overlay attached to request"); return mImpl.registerFabricatedOverlay(fabricated); diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java index e2bf4a46653b..d68cecb41190 100644 --- a/services/core/java/com/android/server/pm/InstallPackageHelper.java +++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java @@ -3476,7 +3476,8 @@ final class InstallPackageHelper { Throwable throwable = parseResult.throwable; ApexInfo ai = parsingApexInfo.get(parseResult.scanFile); int newParseFlags = parseFlags; - int newScanFlags = scanFlags | SCAN_AS_APEX; + int newScanFlags = scanFlags | SCAN_AS_APEX + | mPm.getSystemPackageScanFlags(parseResult.scanFile); if (!ai.isFactory) { newParseFlags &= ~ParsingPackageUtils.PARSE_IS_SYSTEM_DIR; newScanFlags |= SCAN_NEW_INSTALL; diff --git a/services/core/java/com/android/server/pm/InstantAppResolverConnection.java b/services/core/java/com/android/server/pm/InstantAppResolverConnection.java index 4f75f04b11b6..b4c40e6fd361 100644 --- a/services/core/java/com/android/server/pm/InstantAppResolverConnection.java +++ b/services/core/java/com/android/server/pm/InstantAppResolverConnection.java @@ -121,7 +121,7 @@ final class InstantAppResolverConnection implements DeathRecipient { public void sendResult(Bundle data) throws RemoteException { final ArrayList<InstantAppResolveInfo> resolveList = data.getParcelableArrayList( - InstantAppResolverService.EXTRA_RESOLVE_INFO); + InstantAppResolverService.EXTRA_RESOLVE_INFO, android.content.pm.InstantAppResolveInfo.class); callbackHandler.post(() -> callback.onPhaseTwoResolved(resolveList, startTime)); } }; @@ -343,7 +343,7 @@ final class InstantAppResolverConnection implements DeathRecipient { public void sendResult(Bundle data) throws RemoteException { final ArrayList<InstantAppResolveInfo> resolveList = data.getParcelableArrayList( - InstantAppResolverService.EXTRA_RESOLVE_INFO); + InstantAppResolverService.EXTRA_RESOLVE_INFO, android.content.pm.InstantAppResolveInfo.class); int sequence = data.getInt(InstantAppResolverService.EXTRA_SEQUENCE, -1); onRemoteMethodResult(resolveList, sequence); diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 79e5dd2f2304..b7a5f7031046 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -508,7 +508,7 @@ public class UserManagerService extends IUserManager.Stub { if (!ACTION_DISABLE_QUIET_MODE_AFTER_UNLOCK.equals(intent.getAction())) { return; } - final IntentSender target = intent.getParcelableExtra(Intent.EXTRA_INTENT); + final IntentSender target = intent.getParcelableExtra(Intent.EXTRA_INTENT, android.content.IntentSender.class); final int userId = intent.getIntExtra(Intent.EXTRA_USER_ID, UserHandle.USER_NULL); // Call setQuietModeEnabled on bg thread to avoid ANR BackgroundThread.getHandler().post(() -> diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java index 67d9aecf01bd..6a4513d45d8f 100644 --- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java +++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java @@ -1432,7 +1432,7 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, this.processes = in.readHashMap(ParsedProcess.class.getClassLoader()); this.metaData = in.readBundle(boot); this.volumeUuid = sForInternedString.unparcel(in); - this.signingDetails = in.readParcelable(boot); + this.signingDetails = in.readParcelable(boot, android.content.pm.SigningDetails.class); this.mPath = in.readString(); this.queriesIntents = in.createTypedArrayList(Intent.CREATOR); this.queriesPackages = sForInternedStringList.unparcel(in); diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java index 201ca9c4e9cd..b60b9a04d620 100644 --- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java +++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java @@ -3280,7 +3280,7 @@ public class ParsingPackageUtils { ArraySet<PublicKey> keys = new ArraySet<>(M); for (int j = 0; j < M; ++j) { - PublicKey pk = (PublicKey) in.readSerializable(); + PublicKey pk = (PublicKey) in.readSerializable(java.security.PublicKey.class.getClassLoader(), java.security.PublicKey.class); keys.add(pk); } diff --git a/services/core/java/com/android/server/policy/GlobalKeyIntent.java b/services/core/java/com/android/server/policy/GlobalKeyIntent.java index f8682be7c49a..3d34bee0f328 100644 --- a/services/core/java/com/android/server/policy/GlobalKeyIntent.java +++ b/services/core/java/com/android/server/policy/GlobalKeyIntent.java @@ -76,7 +76,7 @@ public final class GlobalKeyIntent { return null; } - final KeyEvent event = intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); + final KeyEvent event = intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT, android.view.KeyEvent.class); final boolean fromNonInteractive = intent.getBooleanExtra(EXTRA_BEGAN_FROM_NON_INTERACTIVE, false); return new GlobalKeyIntent(intent.getComponent(), event, fromNonInteractive); diff --git a/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java b/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java index c354f116af5f..c79bc89efbe9 100644 --- a/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java +++ b/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java @@ -282,7 +282,7 @@ public final class SensorPrivacyService extends SystemService { public void onReceive(Context context, Intent intent) { setToggleSensorPrivacy( ((UserHandle) intent.getParcelableExtra( - Intent.EXTRA_USER)).getIdentifier(), OTHER, + Intent.EXTRA_USER, android.os.UserHandle.class)).getIdentifier(), OTHER, intent.getIntExtra(EXTRA_SENSOR, UNKNOWN), false); } }, new IntentFilter(ACTION_DISABLE_TOGGLE_SENSOR_PRIVACY), diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java index b00d8b47906a..53b8b53e2b6c 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java @@ -27,6 +27,7 @@ import android.view.InsetsVisibilities; import android.view.WindowInsetsController.Appearance; import android.view.WindowInsetsController.Behavior; +import com.android.internal.statusbar.LetterboxDetails; import com.android.internal.view.AppearanceRegion; import com.android.server.notification.NotificationDelegate; @@ -133,7 +134,8 @@ public interface StatusBarManagerInternal { /** @see com.android.internal.statusbar.IStatusBar#onSystemBarAttributesChanged */ void onSystemBarAttributesChanged(int displayId, @Appearance int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, - @Behavior int behavior, InsetsVisibilities requestedVisibilities, String packageName); + @Behavior int behavior, InsetsVisibilities requestedVisibilities, String packageName, + LetterboxDetails[] letterboxDetails); /** @see com.android.internal.statusbar.IStatusBar#showTransient */ void showTransient(int displayId, @InternalInsetsType int[] types, diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index 46e7574e1c8a..71b1bc2e24bc 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -96,6 +96,7 @@ import com.android.internal.statusbar.ISessionListener; import com.android.internal.statusbar.IStatusBar; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.IUndoMediaTransferCallback; +import com.android.internal.statusbar.LetterboxDetails; import com.android.internal.statusbar.NotificationVisibility; import com.android.internal.statusbar.RegisterStatusBarResult; import com.android.internal.statusbar.StatusBarIcon; @@ -596,13 +597,15 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D public void onSystemBarAttributesChanged(int displayId, @Appearance int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, @Behavior int behavior, InsetsVisibilities requestedVisibilities, - String packageName) { + String packageName, LetterboxDetails[] letterboxDetails) { getUiState(displayId).setBarAttributes(appearance, appearanceRegions, - navbarColorManagedByIme, behavior, requestedVisibilities, packageName); + navbarColorManagedByIme, behavior, requestedVisibilities, packageName, + letterboxDetails); if (mBar != null) { try { mBar.onSystemBarAttributesChanged(displayId, appearance, appearanceRegions, - navbarColorManagedByIme, behavior, requestedVisibilities, packageName); + navbarColorManagedByIme, behavior, requestedVisibilities, packageName, + letterboxDetails); } catch (RemoteException ex) { } } } @@ -1204,17 +1207,20 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D private int mImeBackDisposition = 0; private boolean mShowImeSwitcher = false; private IBinder mImeToken = null; + private LetterboxDetails[] mLetterboxDetails; private void setBarAttributes(@Appearance int appearance, AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, @Behavior int behavior, InsetsVisibilities requestedVisibilities, - String packageName) { + String packageName, + LetterboxDetails[] letterboxDetails) { mAppearance = appearance; mAppearanceRegions = appearanceRegions; mNavbarColorManagedByIme = navbarColorManagedByIme; mBehavior = behavior; mRequestedVisibilities = requestedVisibilities; mPackageName = packageName; + mLetterboxDetails = letterboxDetails; } private void showTransient(@InternalInsetsType int[] types) { @@ -1341,7 +1347,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D state.mImeBackDisposition, state.mShowImeSwitcher, gatherDisableActionsLocked(mCurrentUserId, 2), state.mImeToken, state.mNavbarColorManagedByIme, state.mBehavior, state.mRequestedVisibilities, - state.mPackageName, transientBarTypes); + state.mPackageName, transientBarTypes, state.mLetterboxDetails); } } diff --git a/services/core/java/com/android/server/storage/CacheQuotaStrategy.java b/services/core/java/com/android/server/storage/CacheQuotaStrategy.java index ff8b8d2b7b47..fc77ef155952 100644 --- a/services/core/java/com/android/server/storage/CacheQuotaStrategy.java +++ b/services/core/java/com/android/server/storage/CacheQuotaStrategy.java @@ -207,7 +207,7 @@ public class CacheQuotaStrategy implements RemoteCallback.OnResultListener { public void onResult(Bundle data) { final List<CacheQuotaHint> processedRequests = data.getParcelableArrayList( - CacheQuotaService.REQUEST_LIST_KEY); + CacheQuotaService.REQUEST_LIST_KEY, android.app.usage.CacheQuotaHint.class); pushProcessedQuotas(processedRequests); writeXmlToFile(processedRequests); } diff --git a/services/core/java/com/android/server/storage/StorageUserConnection.java b/services/core/java/com/android/server/storage/StorageUserConnection.java index 0b11b0b6d212..27ca83addec8 100644 --- a/services/core/java/com/android/server/storage/StorageUserConnection.java +++ b/services/core/java/com/android/server/storage/StorageUserConnection.java @@ -445,7 +445,7 @@ public final class StorageUserConnection { } private void setResult(Bundle result, CompletableFuture<Void> future) { - ParcelableException ex = result.getParcelable(EXTRA_ERROR); + ParcelableException ex = result.getParcelable(EXTRA_ERROR, android.os.ParcelableException.class); if (ex != null) { future.completeExceptionally(ex); } else { diff --git a/services/core/java/com/android/server/trust/TrustAgentWrapper.java b/services/core/java/com/android/server/trust/TrustAgentWrapper.java index 4b8c7c176fda..0b1f6b9ba285 100644 --- a/services/core/java/com/android/server/trust/TrustAgentWrapper.java +++ b/services/core/java/com/android/server/trust/TrustAgentWrapper.java @@ -132,7 +132,7 @@ public class TrustAgentWrapper { private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - ComponentName component = intent.getParcelableExtra(EXTRA_COMPONENT_NAME); + ComponentName component = intent.getParcelableExtra(EXTRA_COMPONENT_NAME, android.content.ComponentName.class); if (TRUST_EXPIRED_ACTION.equals(intent.getAction()) && mName.equals(component)) { mHandler.removeMessages(MSG_TRUST_TIMEOUT); diff --git a/services/core/java/com/android/server/vr/Vr2dDisplay.java b/services/core/java/com/android/server/vr/Vr2dDisplay.java index 769749038315..51c5a89189c5 100644 --- a/services/core/java/com/android/server/vr/Vr2dDisplay.java +++ b/services/core/java/com/android/server/vr/Vr2dDisplay.java @@ -170,7 +170,7 @@ class Vr2dDisplay { } else if (DEBUG_ACTION_SET_SURFACE.equals(action)) { if (mVirtualDisplay != null) { if (intent.hasExtra(DEBUG_EXTRA_SURFACE)) { - setSurfaceLocked(intent.getParcelableExtra(DEBUG_EXTRA_SURFACE)); + setSurfaceLocked(intent.getParcelableExtra(DEBUG_EXTRA_SURFACE, android.view.Surface.class)); } } else { Log.w(TAG, "Cannot set the surface because the VD is null."); diff --git a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java index a452013bf42a..7d84bdf78056 100644 --- a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java +++ b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java @@ -49,6 +49,7 @@ import android.content.pm.ResolveInfo; import android.content.pm.SuspendDialogInfo; import android.content.pm.UserInfo; import android.os.Bundle; +import android.os.IBinder; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; @@ -64,7 +65,7 @@ import com.android.server.am.ActivityManagerService; import com.android.server.wm.ActivityInterceptorCallback.ActivityInterceptResult; /** - * A class that contains activity intercepting logic for {@link ActivityStarter#startActivityLocked} + * A class that contains activity intercepting logic for {@link ActivityStarter#execute()} * It's initialized via setStates and interception occurs via the intercept method. * * Note that this class is instantiated when {@link ActivityManagerService} gets created so there @@ -104,6 +105,7 @@ class ActivityStartInterceptor { ActivityInfo mAInfo; String mResolvedType; Task mInTask; + TaskFragment mInTaskFragment; ActivityOptions mActivityOptions; ActivityStartInterceptor( @@ -135,15 +137,46 @@ class ActivityStartInterceptor { } private IntentSender createIntentSenderForOriginalIntent(int callingUid, int flags) { - Bundle activityOptions = deferCrossProfileAppsAnimationIfNecessary(); + Bundle bOptions = deferCrossProfileAppsAnimationIfNecessary(); + final TaskFragment taskFragment = getLaunchTaskFragment(); + // If the original intent is going to be embedded, try to forward the embedding TaskFragment + // and its task id to embed back the original intent. + if (taskFragment != null) { + ActivityOptions activityOptions = bOptions != null + ? ActivityOptions.fromBundle(bOptions) + : ActivityOptions.makeBasic(); + activityOptions.setLaunchTaskFragmentToken(taskFragment.getFragmentToken()); + bOptions = activityOptions.toBundle(); + } final IIntentSender target = mService.getIntentSenderLocked( INTENT_SENDER_ACTIVITY, mCallingPackage, mCallingFeatureId, callingUid, mUserId, null /*token*/, null /*resultCode*/, 0 /*requestCode*/, new Intent[] { mIntent }, new String[] { mResolvedType }, - flags, activityOptions); + flags, bOptions); return new IntentSender(target); } + + /** + * A helper function to obtain the targeted {@link TaskFragment} during + * {@link #intercept(Intent, ResolveInfo, ActivityInfo, String, Task, TaskFragment, int, int, + * ActivityOptions)} if any. + */ + @Nullable + private TaskFragment getLaunchTaskFragment() { + if (mInTaskFragment != null) { + return mInTaskFragment; + } + if (mActivityOptions == null) { + return null; + } + final IBinder taskFragToken = mActivityOptions.getLaunchTaskFragmentToken(); + if (taskFragToken == null) { + return null; + } + return TaskFragment.fromTaskFragmentToken(taskFragToken, mService); + } + /** * Intercept the launch intent based on various signals. If an interception happened the * internal variables get assigned and need to be read explicitly by the caller. @@ -151,7 +184,8 @@ class ActivityStartInterceptor { * @return true if an interception occurred */ boolean intercept(Intent intent, ResolveInfo rInfo, ActivityInfo aInfo, String resolvedType, - Task inTask, int callingPid, int callingUid, ActivityOptions activityOptions) { + Task inTask, TaskFragment inTaskFragment, int callingPid, int callingUid, + ActivityOptions activityOptions) { mUserManager = UserManager.get(mServiceContext); mIntent = intent; @@ -161,6 +195,7 @@ class ActivityStartInterceptor { mAInfo = aInfo; mResolvedType = resolvedType; mInTask = inTask; + mInTaskFragment = inTaskFragment; mActivityOptions = activityOptions; if (interceptQuietProfileIfNeeded()) { @@ -332,12 +367,21 @@ class ActivityStartInterceptor { mCallingPid = mRealCallingPid; mCallingUid = mRealCallingUid; mResolvedType = null; + final TaskFragment taskFragment = getLaunchTaskFragment(); // If we are intercepting and there was a task, convert it into an extra for the // ConfirmCredentials intent and unassign it, as otherwise the task will move to // front even if ConfirmCredentials is cancelled. if (mInTask != null) { mIntent.putExtra(EXTRA_TASK_ID, mInTask.mTaskId); mInTask = null; + } else if (taskFragment != null) { + // If the original intent is started to an embedded TaskFragment, append its parent task + // id to extra. It is to embed back the original intent to the TaskFragment with the + // same task. + final Task parentTask = taskFragment.getTask(); + if (parentTask != null) { + mIntent.putExtra(EXTRA_TASK_ID, parentTask.mTaskId); + } } if (mActivityOptions == null) { mActivityOptions = ActivityOptions.makeBasic(); diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index c92cf33063b7..9b1c6bbd9a3a 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -1060,8 +1060,8 @@ class ActivityStarter { mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage, callingFeatureId); - if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid, - callingUid, checkedOptions)) { + if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, inTaskFragment, + callingPid, callingUid, checkedOptions)) { // activity start was intercepted, e.g. because the target user is currently in quiet // mode (turn off work) or the target application is suspended intent = mInterceptor.mIntent; diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index cff8b93ac947..95f76180c600 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -46,6 +46,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP; +import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; @@ -145,6 +146,7 @@ import com.android.internal.policy.GestureNavigationSettingsObserver; import com.android.internal.policy.ScreenDecorationsUtils; import com.android.internal.policy.SystemBarUtils; import com.android.internal.protolog.common.ProtoLog; +import com.android.internal.statusbar.LetterboxDetails; import com.android.internal.util.ScreenshotHelper; import com.android.internal.util.function.TriConsumer; import com.android.internal.view.AppearanceRegion; @@ -1165,7 +1167,8 @@ public class DisplayPolicy { continue; } calculateInsetsFrame(displayFrames, win, inOutFrame, - provider.source, provider.insetsSize + provider.source, provider.insetsSize, + lp.privateFlags, lp.gravity ); } } @@ -1240,21 +1243,25 @@ public class DisplayPolicy { provider.insetsSize != null ? (displayFrames, windowContainer, inOutFrame) -> { inOutFrame.inset(win.mGivenContentInsets); + final LayoutParams lp = + win.mAttrs.forRotation(displayFrames.mRotation); final InsetsFrameProvider ifp = - win.mAttrs.forRotation(displayFrames.mRotation) - .providedInsets[index]; + lp.providedInsets[index]; calculateInsetsFrame(displayFrames, windowContainer, - inOutFrame, ifp.source, ifp.insetsSize); + inOutFrame, ifp.source, ifp.insetsSize, + lp.privateFlags, lp.gravity); } : null; final TriConsumer<DisplayFrames, WindowContainer, Rect> imeFrameProvider = provider.imeInsetsSize != null ? (displayFrames, windowContainer, inOutFrame) -> { inOutFrame.inset(win.mGivenContentInsets); + final LayoutParams lp = + win.mAttrs.forRotation(displayFrames.mRotation); final InsetsFrameProvider ifp = - win.mAttrs.forRotation(displayFrames.mRotation) - .providedInsets[index]; + lp.providedInsets[index]; calculateInsetsFrame(displayFrames, windowContainer, - inOutFrame, ifp.source, ifp.imeInsetsSize); + inOutFrame, ifp.source, ifp.imeInsetsSize, + lp.privateFlags, lp.gravity); } : null; mDisplayContent.setInsetProvider(provider.type, win, frameProvider, imeFrameProvider); @@ -1266,11 +1273,15 @@ public class DisplayPolicy { } private void calculateInsetsFrame(DisplayFrames df, WindowContainer container, Rect inOutFrame, - int source, Insets insetsSize) { + int source, Insets insetsSize, @LayoutParams.PrivateFlags int privateFlags, + int windowGravity) { + boolean extendByCutout = false; if (source == InsetsFrameProvider.SOURCE_DISPLAY) { inOutFrame.set(df.mUnrestricted); } else if (source == InsetsFrameProvider.SOURCE_CONTAINER_BOUNDS) { inOutFrame.set(container.getBounds()); + } else { + extendByCutout = (privateFlags & PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT) != 0; } if (insetsSize == null) { return; @@ -1288,6 +1299,11 @@ public class DisplayPolicy { } else { inOutFrame.setEmpty(); } + + if (extendByCutout) { + WindowLayout.extendFrameByCutout(windowGravity, df.mDisplayCutoutSafe, + df.mUnrestricted, inOutFrame, sTmpRect); + } } @WindowManagerPolicy.AltBarPosition @@ -2399,7 +2415,7 @@ public class DisplayPolicy { mLastStatusBarAppearanceRegions = statusBarAppearanceRegions; callStatusBarSafely(statusBar -> statusBar.onSystemBarAttributesChanged(displayId, appearance, statusBarAppearanceRegions, isNavbarColorManagedByIme, behavior, - requestedVisibilities, focusedApp)); + requestedVisibilities, focusedApp, new LetterboxDetails[]{})); } private void callStatusBarSafely(Consumer<StatusBarManagerInternal> consumer) { diff --git a/services/core/java/com/android/server/wm/EventLogTags.logtags b/services/core/java/com/android/server/wm/EventLogTags.logtags index 6d63331622b9..1e5a219e5e52 100644 --- a/services/core/java/com/android/server/wm/EventLogTags.logtags +++ b/services/core/java/com/android/server/wm/EventLogTags.logtags @@ -66,4 +66,4 @@ option java_package com.android.server.wm 31007 wm_boot_animation_done (time|2|3) # Request surface flinger to show / hide the wallpaper surface. -33001 wm_wallpaper_surface (Display Id|1|5),(visible|1) +33001 wm_wallpaper_surface (Display Id|1|5),(Visible|1),(Target|3) diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java index db2ee2de06ca..ee1ff2cd61ff 100644 --- a/services/core/java/com/android/server/wm/InsetsPolicy.java +++ b/services/core/java/com/android/server/wm/InsetsPolicy.java @@ -265,7 +265,7 @@ class InsetsPolicy { state = originalState; } state = adjustVisibilityForIme(target, state, state == originalState); - return adjustInsetsForRoundedCorners(target, state, state == originalState); + return adjustInsetsForRoundedCorners(target.mToken, state, state == originalState); } InsetsState adjustInsetsForWindow(WindowState target, InsetsState originalState) { @@ -290,7 +290,8 @@ class InsetsPolicy { final InsetsState originalState = mDisplayContent.getInsetsPolicy() .enforceInsetsPolicyForTarget(type, WINDOWING_MODE_FULLSCREEN, alwaysOnTop, mStateController.getRawInsetsState()); - return adjustVisibilityForTransientTypes(originalState); + InsetsState state = adjustVisibilityForTransientTypes(originalState); + return adjustInsetsForRoundedCorners(token, state, state == originalState); } /** @@ -465,15 +466,19 @@ class InsetsPolicy { return originalState; } - private InsetsState adjustInsetsForRoundedCorners(WindowState w, InsetsState originalState, + private InsetsState adjustInsetsForRoundedCorners(WindowToken token, InsetsState originalState, boolean copyState) { - final Task task = w.getTask(); - if (task != null && !task.getWindowConfiguration().tasksAreFloating()) { - // Use task bounds to calculating rounded corners if the task is not floating. - final Rect roundedCornerFrame = new Rect(task.getBounds()); - final InsetsState state = copyState ? new InsetsState(originalState) : originalState; - state.setRoundedCornerFrame(roundedCornerFrame); - return state; + if (token != null) { + final ActivityRecord activityRecord = token.asActivityRecord(); + final Task task = activityRecord != null ? activityRecord.getTask() : null; + if (task != null && !task.getWindowConfiguration().tasksAreFloating()) { + // Use task bounds to calculating rounded corners if the task is not floating. + final Rect roundedCornerFrame = new Rect(task.getBounds()); + final InsetsState state = copyState ? new InsetsState(originalState) + : originalState; + state.setRoundedCornerFrame(roundedCornerFrame); + return state; + } } return originalState; } diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 1525fb3930d6..e65f0bbc1e55 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -738,8 +738,9 @@ class Task extends TaskFragment { "removeTask:" + reason + " deferring removing taskId=" + mTaskId); return; } + final boolean isLeafTask = isLeafTask(); removeImmediately(reason); - if (isLeafTask()) { + if (isLeafTask) { mAtmService.getTaskChangeNotificationController().notifyTaskRemoved(mTaskId); final TaskDisplayArea taskDisplayArea = getDisplayArea(); diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java index fd379bf1d9f4..4a5c4737cbbc 100644 --- a/services/core/java/com/android/server/wm/WindowSurfaceController.java +++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java @@ -126,8 +126,10 @@ class WindowSurfaceController { try { transaction.hide(mSurfaceControl); if (mAnimator.mIsWallpaper) { + final DisplayContent dc = mAnimator.mWin.getDisplayContent(); EventLog.writeEvent(EventLogTags.WM_WALLPAPER_SURFACE, - mAnimator.mWin.getDisplayId(), 0 /* request hidden */); + dc.mDisplayId, 0 /* request hidden */, + String.valueOf(dc.mWallpaperController.getWallpaperTarget())); } } catch (RuntimeException e) { Slog.w(TAG, "Exception hiding surface in " + this); @@ -266,8 +268,10 @@ class WindowSurfaceController { setShown(true); t.show(mSurfaceControl); if (mAnimator.mIsWallpaper) { + final DisplayContent dc = mAnimator.mWin.getDisplayContent(); EventLog.writeEvent(EventLogTags.WM_WALLPAPER_SURFACE, - mAnimator.mWin.getDisplayId(), 1 /* request shown */); + dc.mDisplayId, 1 /* request shown */, + String.valueOf(dc.mWallpaperController.getWallpaperTarget())); } return true; } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index cbd574348de0..7b7106fea0ff 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -18000,7 +18000,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Slogf.i(LOG_TAG, "Account removed from the primary user."); } else { // TODO(174768447): Revisit start activity logic. - final Intent removeIntent = result.getParcelable(AccountManager.KEY_INTENT); + final Intent removeIntent = result.getParcelable(AccountManager.KEY_INTENT, android.content.Intent.class); removeIntent.addFlags(FLAG_ACTIVITY_NEW_TASK); if (removeIntent != null) { Slogf.i(LOG_TAG, "Starting activity to remove account"); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java index 84e89a08e1f4..06cbe787ac90 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java @@ -134,7 +134,7 @@ final class NetworkLoggingHandler extends Handler { public void handleMessage(Message msg) { switch (msg.what) { case LOG_NETWORK_EVENT_MSG: { - final NetworkEvent networkEvent = msg.getData().getParcelable(NETWORK_EVENT_KEY); + final NetworkEvent networkEvent = msg.getData().getParcelable(NETWORK_EVENT_KEY, android.app.admin.NetworkEvent.class); if (networkEvent != null) { Bundle notificationExtras = null; synchronized (NetworkLoggingHandler.this) { diff --git a/services/midi/java/com/android/server/midi/MidiService.java b/services/midi/java/com/android/server/midi/MidiService.java index 994a76700dc0..b519a782ce26 100644 --- a/services/midi/java/com/android/server/midi/MidiService.java +++ b/services/midi/java/com/android/server/midi/MidiService.java @@ -365,7 +365,7 @@ public class MidiService extends IMidiManager.Stub { mServiceInfo = serviceInfo; mUid = uid; mBluetoothDevice = (BluetoothDevice)deviceInfo.getProperties().getParcelable( - MidiDeviceInfo.PROPERTY_BLUETOOTH_DEVICE);; + MidiDeviceInfo.PROPERTY_BLUETOOTH_DEVICE, android.bluetooth.BluetoothDevice.class);; setDeviceServer(server); } @@ -745,7 +745,7 @@ public class MidiService extends IMidiManager.Stub { Log.d(TAG, "BLE Device"); BluetoothDevice btDevice = - intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE, android.bluetooth.BluetoothDevice.class); dumpUuids(btDevice); // See if there are any service UUIDs and if so do any of them indicate a @@ -764,7 +764,7 @@ public class MidiService extends IMidiManager.Stub { { Log.d(TAG, "ACTION_ACL_DISCONNECTED"); BluetoothDevice btDevice = - intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE, android.bluetooth.BluetoothDevice.class); // We DO know at this point if we are disconnecting a MIDI device, so // don't bother if we are not. if (isBLEMIDIDevice(btDevice)) { @@ -793,7 +793,7 @@ public class MidiService extends IMidiManager.Stub { { Log.d(TAG, "ACTION_UUID"); BluetoothDevice btDevice = - intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE, android.bluetooth.BluetoothDevice.class); dumpUuids(btDevice); if (isBLEMIDIDevice(btDevice)) { Log.d(TAG, "BT MIDI DEVICE"); @@ -1165,7 +1165,7 @@ public class MidiService extends IMidiManager.Stub { BluetoothDevice bluetoothDevice = null; if (type == MidiDeviceInfo.TYPE_BLUETOOTH) { bluetoothDevice = (BluetoothDevice)properties.getParcelable( - MidiDeviceInfo.PROPERTY_BLUETOOTH_DEVICE); + MidiDeviceInfo.PROPERTY_BLUETOOTH_DEVICE, android.bluetooth.BluetoothDevice.class); device = mBluetoothDevices.get(bluetoothDevice); if (device != null) { device.setDeviceInfo(deviceInfo); diff --git a/services/people/java/com/android/server/people/prediction/ShareTargetPredictor.java b/services/people/java/com/android/server/people/prediction/ShareTargetPredictor.java index 368b737d2133..b6204073d1cc 100644 --- a/services/people/java/com/android/server/people/prediction/ShareTargetPredictor.java +++ b/services/people/java/com/android/server/people/prediction/ShareTargetPredictor.java @@ -70,7 +70,7 @@ class ShareTargetPredictor extends AppTargetPredictor { @UserIdInt int callingUserId, @NonNull Context context) { super(predictionContext, updatePredictionsMethod, dataManager, callingUserId); mIntentFilter = predictionContext.getExtras().getParcelable( - ChooserActivity.APP_PREDICTION_INTENT_FILTER_KEY); + ChooserActivity.APP_PREDICTION_INTENT_FILTER_KEY, android.content.IntentFilter.class); if (DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI, SystemUiDeviceConfigFlags.DARK_LAUNCH_REMOTE_PREDICTION_SERVICE_ENABLED, false)) { diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java index 73e409abf0c1..1575336600b4 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java @@ -192,7 +192,7 @@ public class ActivityStartInterceptorTest { .thenReturn(PLATFORM_PACKAGE_NAME); // THEN calling intercept returns true - assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); + assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); // THEN the returned intent is the admin support intent assertEquals(ADMIN_SUPPORT_INTENT, mInterceptor.mIntent); @@ -203,7 +203,7 @@ public class ActivityStartInterceptorTest { final String suspendingPackage = "com.test.suspending.package"; final SuspendDialogInfo dialogInfo = suspendPackage(suspendingPackage); // THEN calling intercept returns true - assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); + assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); // Check intent parameters assertEquals(dialogInfo, @@ -234,7 +234,7 @@ public class ActivityStartInterceptorTest { TEST_USER_ID, TEST_PACKAGE_NAME, LOCK_TASK_LAUNCH_MODE_DEFAULT)) .thenReturn(false); - assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); + assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); assertTrue(BlockedAppActivity.createIntent(TEST_USER_ID, TEST_PACKAGE_NAME) .filterEquals(mInterceptor.mIntent)); @@ -246,7 +246,7 @@ public class ActivityStartInterceptorTest { when(mUserManager.isQuietModeEnabled(eq(UserHandle.of(TEST_USER_ID)))).thenReturn(true); // THEN calling intercept returns true - assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); + assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); // THEN the returned intent is the quiet mode intent assertTrue(UnlaunchableAppActivity.createInQuietModeDialogIntent(TEST_USER_ID) @@ -260,7 +260,7 @@ public class ActivityStartInterceptorTest { when(mUserManager.isQuietModeEnabled(eq(UserHandle.of(TEST_USER_ID)))).thenReturn(true); // THEN calling intercept returns true - assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); + assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); // THEN the returned intent is the quiet mode intent assertTrue(UnlaunchableAppActivity.createInQuietModeDialogIntent(TEST_USER_ID) @@ -273,7 +273,7 @@ public class ActivityStartInterceptorTest { when(mAmInternal.shouldConfirmCredentials(TEST_USER_ID)).thenReturn(true); // THEN calling intercept returns true - mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null); + mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null); // THEN the returned intent is the quiet mode intent assertTrue(CONFIRM_CREDENTIALS_INTENT.filterEquals(mInterceptor.mIntent)); @@ -286,7 +286,7 @@ public class ActivityStartInterceptorTest { .thenReturn("This app is bad"); // THEN calling intercept returns true - assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); + assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); // THEN the returned intent is the harmful app warning intent assertEquals(HarmfulAppWarningActivity.class.getName(), @@ -298,7 +298,7 @@ public class ActivityStartInterceptorTest { // GIVEN that none of the interception conditions are met // THEN calling intercept returns false - assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); + assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); } public void addMockInterceptorCallback( @@ -323,7 +323,7 @@ public class ActivityStartInterceptorTest { new Intent("android.test.foo"), ActivityOptions.makeBasic().setLaunchDisplayId(3)); - assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); + assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); assertEquals("android.test.foo", mInterceptor.mIntent.getAction()); assertEquals(3, mInterceptor.mActivityOptions.getLaunchDisplayId()); } @@ -332,7 +332,7 @@ public class ActivityStartInterceptorTest { public void testInterceptionCallback_singleCallbackReturnsNull() { addMockInterceptorCallback(null, null); - assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); + assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); } @Test @@ -340,7 +340,7 @@ public class ActivityStartInterceptorTest { addMockInterceptorCallback(null, null); addMockInterceptorCallback(new Intent("android.test.second"), null); - assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null)); + assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); assertEquals("android.test.second", mInterceptor.mIntent.getAction()); } diff --git a/services/usb/java/com/android/server/usb/MtpNotificationManager.java b/services/usb/java/com/android/server/usb/MtpNotificationManager.java index 8845f118f3a8..70bafc0d5146 100644 --- a/services/usb/java/com/android/server/usb/MtpNotificationManager.java +++ b/services/usb/java/com/android/server/usb/MtpNotificationManager.java @@ -117,7 +117,7 @@ class MtpNotificationManager { @Override public void onReceive(Context context, Intent intent) { final UsbDevice device = - intent.getExtras().<UsbDevice>getParcelable(UsbManager.EXTRA_DEVICE); + intent.getExtras().<UsbDevice>getParcelable(UsbManager.EXTRA_DEVICE, android.hardware.usb.UsbDevice.class); if (device == null) { return; } diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java index 6ea416b54811..85b9f759beac 100644 --- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java @@ -341,8 +341,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser BroadcastReceiver portReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - ParcelableUsbPort port = intent.getParcelableExtra(UsbManager.EXTRA_PORT); - UsbPortStatus status = intent.getParcelableExtra(UsbManager.EXTRA_PORT_STATUS); + ParcelableUsbPort port = intent.getParcelableExtra(UsbManager.EXTRA_PORT, android.hardware.usb.ParcelableUsbPort.class); + UsbPortStatus status = intent.getParcelableExtra(UsbManager.EXTRA_PORT_STATUS, android.hardware.usb.UsbPortStatus.class); mHandler.updateHostState( port.getUsbPort(context.getSystemService(UsbManager.class)), status); } diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java index 5e633ab3aef5..f8df6c6ea8df 100644 --- a/services/usb/java/com/android/server/usb/UsbPortManager.java +++ b/services/usb/java/com/android/server/usb/UsbPortManager.java @@ -1156,7 +1156,7 @@ public class UsbPortManager { switch (msg.what) { case MSG_UPDATE_PORTS: { Bundle b = msg.getData(); - ArrayList<RawPortInfo> PortInfo = b.getParcelableArrayList(PORT_INFO); + ArrayList<RawPortInfo> PortInfo = b.getParcelableArrayList(PORT_INFO, com.android.server.usb.hal.port.RawPortInfo.class); synchronized (mLock) { updatePortsLocked(null, PortInfo); } diff --git a/services/voiceinteraction/TEST_MAPPING b/services/voiceinteraction/TEST_MAPPING index 22a6445843a4..c083e9039731 100644 --- a/services/voiceinteraction/TEST_MAPPING +++ b/services/voiceinteraction/TEST_MAPPING @@ -15,6 +15,14 @@ "exclude-annotation": "androidx.test.filters.FlakyTest" } ] + }, + { + "name": "CtsVoiceInteractionHostTestCases", + "options": [ + { + "exclude-annotation": "androidx.test.filters.FlakyTest" + } + ] } ] } diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java index a061618b1ca7..093e97614b5a 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java @@ -399,8 +399,8 @@ final class VoiceInteractionSessionConnection implements ServiceConnection, final int taskId = data.getInt(ASSIST_TASK_ID); final IBinder activityId = data.getBinder(ASSIST_ACTIVITY_ID); final Bundle assistData = data.getBundle(ASSIST_KEY_DATA); - final AssistStructure structure = data.getParcelable(ASSIST_KEY_STRUCTURE); - final AssistContent content = data.getParcelable(ASSIST_KEY_CONTENT); + final AssistStructure structure = data.getParcelable(ASSIST_KEY_STRUCTURE, android.app.assist.AssistStructure.class); + final AssistContent content = data.getParcelable(ASSIST_KEY_CONTENT, android.app.assist.AssistContent.class); int uid = -1; if (assistData != null) { uid = assistData.getInt(Intent.EXTRA_ASSIST_UID, -1); diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java index bce6809ef32d..f341bc20fe01 100755 --- a/telecomm/java/android/telecom/ConnectionService.java +++ b/telecomm/java/android/telecom/ConnectionService.java @@ -2044,7 +2044,7 @@ public abstract class ConnectionService extends Service { if (isHandover) { PhoneAccountHandle fromPhoneAccountHandle = request.getExtras() != null ? (PhoneAccountHandle) request.getExtras().getParcelable( - TelecomManager.EXTRA_HANDOVER_FROM_PHONE_ACCOUNT) : null; + TelecomManager.EXTRA_HANDOVER_FROM_PHONE_ACCOUNT, android.telecom.PhoneAccountHandle.class) : null; if (!isIncoming) { connection = onCreateOutgoingHandoverConnection(fromPhoneAccountHandle, request); } else { diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index 6fe9bf97c5c3..bfa60ba960ca 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -1445,7 +1445,7 @@ public class ServiceState implements Parcelable { */ @UnsupportedAppUsage private void setFromNotifierBundle(Bundle m) { - ServiceState ssFromBundle = m.getParcelable(EXTRA_SERVICE_STATE); + ServiceState ssFromBundle = m.getParcelable(EXTRA_SERVICE_STATE, android.telephony.ServiceState.class); if (ssFromBundle != null) { copyFrom(ssFromBundle); } diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java index f74ef0fe764a..f1af68f5cfee 100644 --- a/telephony/java/android/telephony/SignalStrength.java +++ b/telephony/java/android/telephony/SignalStrength.java @@ -906,12 +906,12 @@ public class SignalStrength implements Parcelable { @Deprecated @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) private void setFromNotifierBundle(Bundle m) { - mCdma = m.getParcelable("Cdma"); - mGsm = m.getParcelable("Gsm"); - mWcdma = m.getParcelable("Wcdma"); - mTdscdma = m.getParcelable("Tdscdma"); - mLte = m.getParcelable("Lte"); - mNr = m.getParcelable("Nr"); + mCdma = m.getParcelable("Cdma", android.telephony.CellSignalStrengthCdma.class); + mGsm = m.getParcelable("Gsm", android.telephony.CellSignalStrengthGsm.class); + mWcdma = m.getParcelable("Wcdma", android.telephony.CellSignalStrengthWcdma.class); + mTdscdma = m.getParcelable("Tdscdma", android.telephony.CellSignalStrengthTdscdma.class); + mLte = m.getParcelable("Lte", android.telephony.CellSignalStrengthLte.class); + mNr = m.getParcelable("Nr", android.telephony.CellSignalStrengthNr.class); } /** diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 432d08725e87..24374ee64719 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -4867,7 +4867,7 @@ public class TelephonyManager { return; } ParcelUuid resultUuid = - result.getParcelable(KEY_CALL_COMPOSER_PICTURE_HANDLE); + result.getParcelable(KEY_CALL_COMPOSER_PICTURE_HANDLE, android.os.ParcelUuid.class); if (resultUuid == null) { Log.e(TAG, "Got null uuid without an error" + " while uploading call composer pic"); @@ -10375,7 +10375,7 @@ public class TelephonyManager { protected void onReceiveResult(int resultCode, Bundle ussdResponse) { Rlog.d(TAG, "USSD:" + resultCode); checkNotNull(ussdResponse, "ussdResponse cannot be null."); - UssdResponse response = ussdResponse.getParcelable(USSD_RESPONSE); + UssdResponse response = ussdResponse.getParcelable(USSD_RESPONSE, android.telephony.UssdResponse.class); if (resultCode == USSD_RETURN_SUCCESS) { callback.onReceiveUssdResponse(telephonyManager, response.getUssdRequest(), @@ -16867,7 +16867,7 @@ public class TelephonyManager { } NetworkSlicingConfig slicingConfig = - result.getParcelable(KEY_SLICING_CONFIG_HANDLE); + result.getParcelable(KEY_SLICING_CONFIG_HANDLE, android.telephony.data.NetworkSlicingConfig.class); executor.execute(() -> callback.onResult(slicingConfig)); } }); diff --git a/telephony/java/android/telephony/VisualVoicemailService.java b/telephony/java/android/telephony/VisualVoicemailService.java index fe30eb7bb005..a530917a271c 100644 --- a/telephony/java/android/telephony/VisualVoicemailService.java +++ b/telephony/java/android/telephony/VisualVoicemailService.java @@ -157,14 +157,14 @@ public abstract class VisualVoicemailService extends Service { @Override public void handleMessage(final Message msg) { final PhoneAccountHandle handle = msg.getData() - .getParcelable(DATA_PHONE_ACCOUNT_HANDLE); + .getParcelable(DATA_PHONE_ACCOUNT_HANDLE, android.telecom.PhoneAccountHandle.class); VisualVoicemailTask task = new VisualVoicemailTask(msg.replyTo, msg.arg1); switch (msg.what) { case MSG_ON_CELL_SERVICE_CONNECTED: onCellServiceConnected(task, handle); break; case MSG_ON_SMS_RECEIVED: - VisualVoicemailSms sms = msg.getData().getParcelable(DATA_SMS); + VisualVoicemailSms sms = msg.getData().getParcelable(DATA_SMS, android.telephony.VisualVoicemailSms.class); onSmsReceived(task, sms); break; case MSG_ON_SIM_REMOVED: diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java index 1252dc178cb9..7d63688025e0 100644 --- a/telephony/java/android/telephony/euicc/EuiccManager.java +++ b/telephony/java/android/telephony/euicc/EuiccManager.java @@ -1001,7 +1001,7 @@ public class EuiccManager { public void startResolutionActivity(Activity activity, int requestCode, Intent resultIntent, PendingIntent callbackIntent) throws IntentSender.SendIntentException { PendingIntent resolutionIntent = - resultIntent.getParcelableExtra(EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT); + resultIntent.getParcelableExtra(EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT, android.app.PendingIntent.class); if (resolutionIntent == null) { throw new IllegalArgumentException("Invalid result intent"); } @@ -1032,7 +1032,7 @@ public class EuiccManager { if (!isEnabled()) { PendingIntent callbackIntent = resolutionIntent.getParcelableExtra( - EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT); + EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT, android.app.PendingIntent.class); if (callbackIntent != null) { sendUnavailableError(callbackIntent); } diff --git a/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java b/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java index dd1061f3bd46..556d6f4565d4 100644 --- a/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java +++ b/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java @@ -195,7 +195,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { return false; } DownloadRequest request = intent.getParcelableExtra( - MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST); + MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST, android.telephony.mbms.DownloadRequest.class); String expectedTokenFileName = request.getHash() + DOWNLOAD_TOKEN_SUFFIX; File expectedTokenFile = new File( MbmsUtils.getEmbmsTempFileDirForService(context, request.getFileServiceId()), @@ -236,7 +236,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { private void moveDownloadedFile(Context context, Intent intent) { DownloadRequest request = intent.getParcelableExtra( - MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST); + MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST, android.telephony.mbms.DownloadRequest.class); Intent intentForApp = request.getIntentForApp(); if (intentForApp == null) { Log.i(LOG_TAG, "Malformed app notification intent"); @@ -256,7 +256,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { return; } - Uri finalTempFile = intent.getParcelableExtra(VendorUtils.EXTRA_FINAL_URI); + Uri finalTempFile = intent.getParcelableExtra(VendorUtils.EXTRA_FINAL_URI, android.net.Uri.class); if (!verifyTempFilePath(context, request.getFileServiceId(), finalTempFile)) { Log.w(LOG_TAG, "Download result specified an invalid temp file " + finalTempFile); setResultCode(RESULT_DOWNLOAD_FINALIZATION_ERROR); @@ -264,7 +264,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { } FileInfo completedFileInfo = - (FileInfo) intent.getParcelableExtra(MbmsDownloadSession.EXTRA_MBMS_FILE_INFO); + (FileInfo) intent.getParcelableExtra(MbmsDownloadSession.EXTRA_MBMS_FILE_INFO, android.telephony.mbms.FileInfo.class); Path appSpecifiedDestination = FileSystems.getDefault().getPath( request.getDestinationUri().getPath()); @@ -288,13 +288,13 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { private void cleanupPostMove(Context context, Intent intent) { DownloadRequest request = intent.getParcelableExtra( - MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST); + MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST, android.telephony.mbms.DownloadRequest.class); if (request == null) { Log.w(LOG_TAG, "Intent does not include a DownloadRequest. Ignoring."); return; } - List<Uri> tempFiles = intent.getParcelableArrayListExtra(VendorUtils.EXTRA_TEMP_LIST); + List<Uri> tempFiles = intent.getParcelableArrayListExtra(VendorUtils.EXTRA_TEMP_LIST, android.net.Uri.class); if (tempFiles == null) { return; } @@ -318,7 +318,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { return; } int fdCount = intent.getIntExtra(VendorUtils.EXTRA_FD_COUNT, 0); - List<Uri> pausedList = intent.getParcelableArrayListExtra(VendorUtils.EXTRA_PAUSED_LIST); + List<Uri> pausedList = intent.getParcelableArrayListExtra(VendorUtils.EXTRA_PAUSED_LIST, android.net.Uri.class); if (fdCount == 0 && (pausedList == null || pausedList.size() == 0)) { Log.i(LOG_TAG, "No temp files actually requested. Ending."); @@ -417,7 +417,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { String serviceId = intent.getStringExtra(VendorUtils.EXTRA_SERVICE_ID); File tempFileDir = MbmsUtils.getEmbmsTempFileDirForService(context, serviceId); final List<Uri> filesInUse = - intent.getParcelableArrayListExtra(VendorUtils.EXTRA_TEMP_FILES_IN_USE); + intent.getParcelableArrayListExtra(VendorUtils.EXTRA_TEMP_FILES_IN_USE, android.net.Uri.class); File[] filesToDelete = tempFileDir.listFiles(new FileFilter() { @Override public boolean accept(File file) { diff --git a/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java b/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java index ab83997c67fc..0375f66069c3 100644 --- a/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java +++ b/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java @@ -66,6 +66,7 @@ import java.util.function.Consumer; @RunWith(JUnit4.class) public class StagedInstallInternalTest { private static final String APK_IN_APEX_TESTAPEX_NAME = "com.android.apex.apkrollback.test"; + private static final String REBOOTLESS_APEX_PACKAGE_NAME = "test.apex.rebootless"; private static final TestApp TEST_APEX_WITH_APK_V2 = new TestApp("TestApexWithApkV2", APK_IN_APEX_TESTAPEX_NAME, 2, /*isApex*/true, APK_IN_APEX_TESTAPEX_NAME + "_v2.apex"); private static final TestApp APEX_WRONG_SHA_V2 = new TestApp( @@ -594,6 +595,28 @@ public class StagedInstallInternalTest { assertThat(InstallUtils.getInstalledVersion(packageName)).isEqualTo(1); } + @Test + public void testVendorApex_VerifyFactory() throws Exception { + final PackageManager pm = + InstrumentationRegistry.getInstrumentation().getContext().getPackageManager(); + PackageInfo pi = pm.getPackageInfo(REBOOTLESS_APEX_PACKAGE_NAME, PackageManager.MATCH_APEX); + assertThat(pi.getLongVersionCode()).isEqualTo(1); + assertThat(pi.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) + .isEqualTo(ApplicationInfo.PRIVATE_FLAG_VENDOR); + assertThat(pi.applicationInfo.sourceDir).startsWith("/vendor/apex"); + } + + @Test + public void testVendorApex_VerifyData() throws Exception { + final PackageManager pm = + InstrumentationRegistry.getInstrumentation().getContext().getPackageManager(); + PackageInfo pi = pm.getPackageInfo(REBOOTLESS_APEX_PACKAGE_NAME, PackageManager.MATCH_APEX); + assertThat(pi.getLongVersionCode()).isEqualTo(2); + assertThat(pi.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) + .isEqualTo(ApplicationInfo.PRIVATE_FLAG_VENDOR); + assertThat(pi.applicationInfo.sourceDir).startsWith("/data/apex"); + } + private IPackageManagerNative getPackageManagerNative() { IBinder binder = ServiceManager.waitForService("package_native"); assertThat(binder).isNotNull(); diff --git a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java index 7e0a55ff3f3e..7b17778730eb 100644 --- a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java +++ b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java @@ -63,6 +63,8 @@ public class StagedInstallInternalTest extends BaseHostJUnit4Test { private static final String APK_IN_APEX_TESTAPEX_NAME = "com.android.apex.apkrollback.test"; private static final String APEXD_TEST_APEX = "apex.apexd_test.apex"; private static final String FAKE_APEX_SYSTEM_SERVER_APEX = "test_com.android.server.apex"; + private static final String REBOOTLESS_V1 = "test.rebootless_apex_v1.apex"; + private static final String REBOOTLESS_V2 = "test.rebootless_apex_v2.apex"; private static final String TEST_VENDOR_APEX_ALLOW_LIST = "/vendor/etc/sysconfig/test-vendor-apex-allow-list.xml"; @@ -94,6 +96,7 @@ public class StagedInstallInternalTest extends BaseHostJUnit4Test { "/data/apex/active/" + APK_IN_APEX_TESTAPEX_NAME + "*.apex", "/data/apex/active/" + SHIM_APEX_PACKAGE_NAME + "*.apex", "/system/apex/test.rebootless_apex_v*.apex", + "/vendor/apex/test.rebootless_apex_v*.apex", "/data/apex/active/test.apex.rebootless*.apex", "/system/app/TestApp/TestAppAv1.apk", TEST_VENDOR_APEX_ALLOW_LIST); @@ -137,13 +140,17 @@ public class StagedInstallInternalTest extends BaseHostJUnit4Test { } private void pushTestApex(String fileName) throws Exception { + pushTestApex(fileName, "system"); + } + + private void pushTestApex(String fileName, String partition) throws Exception { CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(getBuild()); final File apex = buildHelper.getTestFile(fileName); if (!getDevice().isAdbRoot()) { getDevice().enableAdbRoot(); } getDevice().remountSystemWritable(); - assertTrue(getDevice().pushFile(apex, "/system/apex/" + fileName)); + assertTrue(getDevice().pushFile(apex, "/" + partition + "/apex/" + fileName)); } private void pushTestVendorApexAllowList(String installerPackageName) throws Exception { @@ -497,6 +504,33 @@ public class StagedInstallInternalTest extends BaseHostJUnit4Test { runPhase("testVendorApexCorrectInstaller_nonStaged"); } + /** + * Tests correctness of {@link android.content.pm.ApplicationInfo} for APEXes on /vendor. + */ + @Test + @LargeTest + public void testVendorApex_Staged() throws Exception { + pushTestApex(REBOOTLESS_V1, "vendor"); + getDevice().reboot(); + runPhase("testVendorApex_VerifyFactory"); + installPackage(REBOOTLESS_V2, "--staged"); + getDevice().reboot(); + runPhase("testVendorApex_VerifyData"); + } + + /** + * Tests correctness of {@link android.content.pm.ApplicationInfo} for APEXes on /vendor. + */ + @Test + @LargeTest + public void testVendorApex_NonStaged() throws Exception { + pushTestApex(REBOOTLESS_V1, "vendor"); + getDevice().reboot(); + runPhase("testVendorApex_VerifyFactory"); + installPackage(REBOOTLESS_V2, "--force-non-staged"); + runPhase("testVendorApex_VerifyData"); + } + @Test public void testRebootlessUpdates() throws Exception { pushTestApex("test.rebootless_apex_v1.apex"); |