OSDN Git Service

Fix wrong app is launched after solving challenge from tapping notification
authorTony Mak <tonymak@google.com>
Thu, 21 Apr 2016 15:43:08 +0000 (16:43 +0100)
committerTony Mak <tonymak@google.com>
Thu, 21 Apr 2016 15:43:08 +0000 (16:43 +0100)
PendingIntent.FLAG_ONE_SHOT is needed to prevent the PendingIntent being
reused.

Also, flag and activity option of credential intent in BaseStatusBar
is not same as the one in ActivityStarter. Added a new
function startConfirmDeviceCredentialIntent in AM to centralize it.

Change-Id: I2d9e5923ad5d4d012f10057c409c666c8ca299a3
Fix: 28309964

core/java/android/app/ActivityManagerNative.java
core/java/android/app/IActivityManager.java
packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
services/core/java/com/android/server/am/ActivityManagerService.java
services/core/java/com/android/server/am/ActivityStarter.java

index ae2ca84..a3f3b2b 100644 (file)
@@ -2959,6 +2959,13 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
             reply.writeNoException();
             return true;
         }
+        case START_CONFIRM_DEVICE_CREDENTIAL_INTENT: {
+            data.enforceInterface(IActivityManager.descriptor);
+            final Intent intent = Intent.CREATOR.createFromParcel(data);
+            startConfirmDeviceCredentialIntent(intent);
+            reply.writeNoException();
+            return true;
+        }
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -6931,5 +6938,16 @@ class ActivityManagerProxy implements IActivityManager
         reply.recycle();
     }
 
+    public void startConfirmDeviceCredentialIntent(Intent intent) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        intent.writeToParcel(data, 0);
+        mRemote.transact(START_CONFIRM_DEVICE_CREDENTIAL_INTENT, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
     private IBinder mRemote;
 }
index b28b5e6..66b4fcf 100644 (file)
@@ -649,6 +649,8 @@ public interface IActivityManager extends IInterface {
 
     public void notifyLockedProfile(@UserIdInt int userId) throws RemoteException;
 
+    public void startConfirmDeviceCredentialIntent(Intent intent) throws RemoteException;
+
     /*
      * Private non-Binder interfaces
      */
@@ -1032,4 +1034,5 @@ public interface IActivityManager extends IInterface {
     int IS_VR_PACKAGE_ENABLED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 371;
     int SWAP_DOCKED_AND_FULLSCREEN_STACK = IBinder.FIRST_CALL_TRANSACTION + 372;
     int NOTIFY_LOCKED_PROFILE = IBinder.FIRST_CALL_TRANSACTION + 373;
+    int START_CONFIRM_DEVICE_CREDENTIAL_INTENT = IBinder.FIRST_CALL_TRANSACTION + 374;
 }
index 2d5b6d4..8bf32c2 100644 (file)
@@ -537,8 +537,7 @@ public abstract class BaseStatusBar extends SystemUI implements
                     );
                 }
             } else if (WORK_CHALLENGE_UNLOCKED_NOTIFICATION_ACTION.equals(action)) {
-                final IntentSender intentSender = (IntentSender) intent
-                        .getParcelableExtra(Intent.EXTRA_INTENT);
+                final IntentSender intentSender = intent.getParcelableExtra(Intent.EXTRA_INTENT);
                 final String notificationKey = intent.getStringExtra(Intent.EXTRA_INDEX);
                 try {
                     mContext.startIntentSender(intentSender, null, 0, 0, 0);
@@ -1924,11 +1923,23 @@ public abstract class BaseStatusBar extends SystemUI implements
             callBackIntent.putExtra(Intent.EXTRA_INDEX, notificationKey);
             callBackIntent.setPackage(mContext.getPackageName());
 
-            newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_CLEAR_TASK);
-            newIntent.putExtra(Intent.EXTRA_INTENT, PendingIntent
-                    .getBroadcast(mContext, 0, callBackIntent, 0).getIntentSender());
-            mContext.startActivity(newIntent);
+            PendingIntent callBackPendingIntent = PendingIntent.getBroadcast(
+                    mContext,
+                    0,
+                    callBackIntent,
+                    PendingIntent.FLAG_CANCEL_CURRENT |
+                            PendingIntent.FLAG_ONE_SHOT |
+                            PendingIntent.FLAG_IMMUTABLE
+            );
+            newIntent.putExtra(
+                    Intent.EXTRA_INTENT,
+                    callBackPendingIntent.getIntentSender()
+            );
+            try {
+                ActivityManagerNative.getDefault().startConfirmDeviceCredentialIntent(newIntent);
+            } catch (RemoteException ex) {
+                // ignore
+            }
             return true;
         }
 
index d7afc13..bc64fe0 100644 (file)
@@ -11502,6 +11502,19 @@ public final class ActivityManagerService extends ActivityManagerNative
     }
 
     @Override
+    public void startConfirmDeviceCredentialIntent(Intent intent) {
+        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
+        synchronized (this) {
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                mActivityStarter.startConfirmCredentialIntent(intent);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+    }
+
+    @Override
     public void stopAppSwitches() {
         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
                 != PackageManager.PERMISSION_GRANTED) {
index 3ffdb95..4da6976 100644 (file)
@@ -33,6 +33,7 @@ import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
+import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
 import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT;
 import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
@@ -612,11 +613,6 @@ class ActivityStarter {
                 .getSystemService(Context.KEYGUARD_SERVICE);
         final Intent credential =
                 km.createConfirmDeviceCredentialIntent(null, null, userId);
-        credential.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
-                Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
-                Intent.FLAG_ACTIVITY_TASK_ON_HOME);
-        final ActivityOptions options = ActivityOptions.makeBasic();
-        options.setLaunchTaskId(mSupervisor.getHomeActivity().task.taskId);
         final ActivityRecord activityRecord = targetStack.topRunningActivityLocked();
         if (activityRecord != null) {
             final IIntentSender target = mService.getIntentSenderLocked(
@@ -633,11 +629,19 @@ class ActivityStarter {
                     null);
             credential.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
             // Show confirm credentials activity.
-            mService.mContext.startActivityAsUser(credential, options.toBundle(),
-                    UserHandle.CURRENT);
+            startConfirmCredentialIntent(credential);
         }
     }
 
+    void startConfirmCredentialIntent(Intent intent) {
+        intent.addFlags(FLAG_ACTIVITY_NEW_TASK |
+                FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
+                FLAG_ACTIVITY_TASK_ON_HOME);
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchTaskId(mSupervisor.getHomeActivity().task.taskId);
+        mService.mContext.startActivityAsUser(intent, options.toBundle(),
+                UserHandle.CURRENT);
+    }
 
     final int startActivityMayWait(IApplicationThread caller, int callingUid,
             String callingPackage, Intent intent, String resolvedType,