1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.internal.app;
18 
19 import android.annotation.NonNull;
20 import android.app.Activity;
21 import android.app.KeyguardManager;
22 import android.content.Intent;
23 import android.content.IntentSender;
24 import android.os.Bundle;
25 import android.util.Slog;
26 
27 import java.util.Objects;
28 
29 /**
30  * Activity used to intercept lock screen intents and show the bouncer before launching the
31  * original intent.
32  */
33 public class LaunchAfterAuthenticationActivity extends Activity {
34     private static final String TAG = LaunchAfterAuthenticationActivity.class.getSimpleName();
35     private static final String EXTRA_ON_SUCCESS_INTENT =
36             "com.android.internal.app.extra.ON_SUCCESS_INTENT";
37 
38     /**
39      * Builds the intent used to launch this activity.
40      *
41      * @param onSuccessIntent The intent to launch after the user has authenticated.
42      */
createLaunchAfterAuthenticationIntent(IntentSender onSuccessIntent)43     public static Intent createLaunchAfterAuthenticationIntent(IntentSender onSuccessIntent) {
44         return new Intent()
45                 .setClassName(/* packageName= */"android",
46                         LaunchAfterAuthenticationActivity.class.getName())
47                 .putExtra(EXTRA_ON_SUCCESS_INTENT, onSuccessIntent)
48                 .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
49                         | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
50     }
51 
52     @Override
onCreate(Bundle icicle)53     public void onCreate(Bundle icicle) {
54         super.onCreate(icicle);
55 
56         final IntentSender onSuccessIntent = getIntent().getParcelableExtra(
57                 EXTRA_ON_SUCCESS_INTENT, android.content.IntentSender.class);
58         requestDismissKeyguardIfNeeded(onSuccessIntent);
59     }
60 
requestDismissKeyguardIfNeeded(IntentSender onSuccessIntent)61     private void requestDismissKeyguardIfNeeded(IntentSender onSuccessIntent) {
62         final KeyguardManager km = Objects.requireNonNull(getSystemService(KeyguardManager.class));
63         if (km.isKeyguardLocked()) {
64             km.requestDismissKeyguard(this,
65                     new KeyguardManager.KeyguardDismissCallback() {
66                         @Override
67                         public void onDismissCancelled() {
68                             LaunchAfterAuthenticationActivity.this.finish();
69                         }
70 
71                         @Override
72                         public void onDismissSucceeded() {
73                             if (onSuccessIntent != null) {
74                                 onUnlocked(onSuccessIntent);
75                             }
76                             LaunchAfterAuthenticationActivity.this.finish();
77                         }
78 
79                         @Override
80                         public void onDismissError() {
81                             Slog.e(TAG, "Error while dismissing keyguard.");
82                             LaunchAfterAuthenticationActivity.this.finish();
83                         }
84                     });
85         } else {
86             finish();
87         }
88     }
89 
onUnlocked(@onNull IntentSender targetIntent)90     private void onUnlocked(@NonNull IntentSender targetIntent) {
91         try {
92             targetIntent.sendIntent(
93                     /* context= */ this,
94                     /* code= */ 0,
95                     /* intent= */null,
96                     /* onFinished= */ null,
97                     /* handler= */ null);
98         } catch (IntentSender.SendIntentException e) {
99             Slog.e(TAG, "Error while sending original intent", e);
100         }
101     }
102 }
103