1 /*
2  * Copyright (C) 2023 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 android.server.wm.backgroundactivity.common;
18 
19 import static android.server.wm.backgroundactivity.common.CommonComponents.EVENT_NOTIFIER_EXTRA;
20 
21 import android.app.Activity;
22 import android.app.PendingIntent;
23 import android.app.Service;
24 import android.content.ComponentName;
25 import android.content.Intent;
26 import android.content.IntentSender;
27 import android.os.Binder;
28 import android.os.Bundle;
29 import android.os.IBinder;
30 import android.os.ResultReceiver;
31 import android.os.storage.StorageManager;
32 import android.util.Log;
33 import android.view.View;
34 import android.view.textclassifier.TextClassification;
35 
36 import java.util.UUID;
37 
38 public class TestService extends Service {
39     static final String TAG = TestService.class.getName();
40     private final ITestService mBinder = new MyBinder();
41 
42     // The latest ForegroundActivity created. It is stored to start a PendingIntent.
43     public static Activity sLatestForegroundActivity;
44 
45     @Override
onBind(Intent intent)46     public IBinder onBind(Intent intent) {
47         return mBinder.asBinder();
48     }
49 
50     private class MyBinder extends ITestService.Stub {
51         @Override
generatePendingIntent(ComponentName componentName, int flags, Bundle createOptions, ResultReceiver resultReceiver)52         public PendingIntent generatePendingIntent(ComponentName componentName, int flags,
53                 Bundle createOptions, ResultReceiver resultReceiver) {
54             Intent intent = new Intent();
55             intent.setComponent(componentName);
56             intent.addFlags(flags);
57             intent.setIdentifier(UUID.randomUUID().toString());
58             intent.putExtra(EVENT_NOTIFIER_EXTRA, resultReceiver);
59             return PendingIntent.getActivity(TestService.this, 0, intent,
60                     PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE,
61                     createOptions);
62         }
63 
64         @Override
generatePendingIntentBroadcast(ComponentName componentName, ResultReceiver resultReceiver)65         public PendingIntent generatePendingIntentBroadcast(ComponentName componentName,
66                 ResultReceiver resultReceiver) {
67             Intent intent = new Intent();
68             intent.setComponent(componentName);
69             intent.setIdentifier(UUID.randomUUID().toString());
70             intent.putExtra(EVENT_NOTIFIER_EXTRA, resultReceiver);
71             return PendingIntent.getBroadcast(TestService.this, 0, intent,
72                     PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
73         }
74 
75         @Override
startManageSpaceActivity()76         public void startManageSpaceActivity() {
77             final long token = Binder.clearCallingIdentity();
78             try {
79                 StorageManager stm = getSystemService(StorageManager.class);
80                 PendingIntent pi = stm.getManageSpaceActivityIntent(getPackageName(), 0);
81                 pi.send();
82             } catch (IllegalArgumentException e) {
83                 throw e;
84             } catch (Exception e) {
85                 Log.e(TAG, "startManageSpaceActivity failed", e);
86                 throw new IllegalStateException("Unable to send PendingIntent");
87             } finally {
88                 Binder.restoreCallingIdentity(token);
89             }
90         }
91 
92         @Override
sendByTextClassification(TextClassification classification)93         public void sendByTextClassification(TextClassification classification) {
94             View.OnClickListener onClickListener = classification.getOnClickListener();
95             onClickListener.onClick(null);
96         }
97 
98         @Override
sendPendingIntent(PendingIntent pendingIntent, Bundle sendOptions)99         public void sendPendingIntent(PendingIntent pendingIntent, Bundle sendOptions) {
100             try {
101                 pendingIntent.send(sendOptions);
102             } catch (IllegalArgumentException e) {
103                 throw e;
104             } catch (Exception e) {
105                 Log.e(TAG, "sendPendingIntent failed", e);
106                 throw new AssertionError(e);
107             }
108         }
109 
110         @Override
sendPendingIntentWithActivityForResult(PendingIntent pendingIntent, Bundle sendOptions)111         public void sendPendingIntentWithActivityForResult(PendingIntent pendingIntent,
112                 Bundle sendOptions) {
113             try {
114                 sLatestForegroundActivity.startIntentSenderForResult(
115                         pendingIntent.getIntentSender(), /*requestCode*/1, /*fillinIntent*/
116                         null, /*flagsMask*/0, /*flagsValue*/0, /*extraFlags*/0);
117             } catch (IllegalArgumentException e) {
118                 throw e;
119             } catch (Exception e) {
120                 Log.e(TAG, "sendPendingIntentForResult failed", e);
121                 throw new AssertionError(e);
122             }
123         }
124 
125         @Override
sendPendingIntentWithActivity(PendingIntent pendingIntent, Bundle sendOptions)126         public void sendPendingIntentWithActivity(PendingIntent pendingIntent,
127                 Bundle sendOptions) {
128             try {
129                 sLatestForegroundActivity.startIntentSender(
130                         pendingIntent.getIntentSender(), /*fillinIntent*/
131                         null, /*flagsMask*/0, /*flagsValue*/0, /*extraFlags*/0);
132             } catch (IllegalArgumentException e) {
133                 throw e;
134             } catch (Exception e) {
135                 Log.e(TAG, "sendPendingIntent failed", e);
136                 throw new AssertionError(e);
137             }
138         }
139 
140         @Override
sendIntentSender(IntentSender intentSender, Bundle sendOptions)141         public void sendIntentSender(IntentSender intentSender,
142                 Bundle sendOptions) {
143             try {
144                 intentSender.sendIntent(getApplicationContext(), /*code*/0, /*intent*/null,
145                         /*onFinished*/null, /*handler*/null, /*requiredPermission*/null);
146             } catch (IllegalArgumentException e) {
147                 throw e;
148             } catch (Exception e) {
149                 Log.e(TAG, "sendIntentSender failed", e);
150                 throw new AssertionError(e);
151             }
152         }
153 
154         @Override
startActivityIntent(Intent intent)155         public void startActivityIntent(Intent intent) {
156             try {
157                 startActivity(intent);
158             } catch (IllegalArgumentException e) {
159                 throw e;
160             } catch (Exception e) {
161                 Log.e(TAG, "startActivityIntent failed", e);
162                 throw new AssertionError(e);
163             }
164         }
165     }
166 }
167