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 package com.android.cts.appsearch.helper;
17 
18 import static com.android.server.appsearch.testing.AppSearchTestUtils.checkIsBatchResultSuccess;
19 import static com.android.server.appsearch.testing.AppSearchTestUtils.convertSearchResultsToDocuments;
20 
21 import android.app.Service;
22 import android.app.appsearch.AppSearchManager;
23 import android.app.appsearch.AppSearchSessionShim;
24 import android.app.appsearch.GenericDocument;
25 import android.app.appsearch.GlobalSearchSessionShim;
26 import android.app.appsearch.PutDocumentsRequest;
27 import android.app.appsearch.SearchResultsShim;
28 import android.app.appsearch.SearchSpec;
29 import android.app.appsearch.SetSchemaRequest;
30 import android.content.Intent;
31 import android.os.IBinder;
32 import android.util.Log;
33 
34 import com.android.cts.appsearch.ICommandReceiver;
35 import com.android.server.appsearch.testing.AppSearchEmail;
36 import com.android.server.appsearch.testing.AppSearchSessionShimImpl;
37 import com.android.server.appsearch.testing.GlobalSearchSessionShimImpl;
38 
39 import java.util.ArrayList;
40 import java.util.Collections;
41 import java.util.List;
42 import java.util.concurrent.Executors;
43 
44 public class AppSearchTestService extends Service {
45 
46     private static final String TAG = "AppSearchTestService";
47     private GlobalSearchSessionShim mGlobalSearchSessionShim;
48     private AppSearchSessionShim mAppSearchSessionShim;
49 
50     @Override
onCreate()51     public void onCreate() {
52         try {
53             // We call this here so we can pass in a context. If we try to create the session in the
54             // stub, it'll try to grab the context from ApplicationProvider. But that will fail
55             // since this isn't instrumented.
56             mGlobalSearchSessionShim =
57                     GlobalSearchSessionShimImpl.createGlobalSearchSession(this).get();
58 
59             mAppSearchSessionShim =
60                     AppSearchSessionShimImpl.createSearchSession(
61                                     this,
62                                     new AppSearchManager.SearchContext.Builder("database").build(),
63                                     Executors.newCachedThreadPool())
64                             .get();
65         } catch (Exception e) {
66             Log.e(TAG, "Error starting service.", e);
67         }
68     }
69 
70     @Override
onBind(Intent intent)71     public IBinder onBind(Intent intent) {
72         return new CommandReceiver();
73     }
74 
75     private class CommandReceiver extends ICommandReceiver.Stub {
76 
77         @Override
globalSearch(String queryExpression)78         public List<String> globalSearch(String queryExpression) {
79             try {
80                 final SearchSpec searchSpec =
81                         new SearchSpec.Builder()
82                                 .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
83                                 .build();
84                 SearchResultsShim searchResults =
85                         mGlobalSearchSessionShim.search(queryExpression, searchSpec);
86                 List<GenericDocument> results = convertSearchResultsToDocuments(searchResults);
87 
88                 List<String> resultStrings = new ArrayList<>();
89                 for (GenericDocument doc : results) {
90                     resultStrings.add(doc.toString());
91                 }
92 
93                 return resultStrings;
94             } catch (Exception e) {
95                 Log.e(TAG, "Error issuing global search.", e);
96                 return Collections.emptyList();
97             }
98         }
99 
100         @Override
indexGloballySearchableDocument()101         public boolean indexGloballySearchableDocument() {
102             try {
103                 // By default, schemas/documents are globally searchable. We don't purposely set
104                 // setSchemaTypeDisplayedBySystem(false) for this schema.
105                 mAppSearchSessionShim
106                         .setSchema(
107                                 new SetSchemaRequest.Builder()
108                                         .addSchemas(AppSearchEmail.SCHEMA)
109                                         .build())
110                         .get();
111 
112                 AppSearchEmail emailDocument =
113                         new AppSearchEmail.Builder("namespace", "id1")
114                                 .setFrom("from@example.com")
115                                 .setTo("to1@example.com", "to2@example.com")
116                                 .setSubject("subject")
117                                 .setBody("this is the body of the email")
118                                 .build();
119                 checkIsBatchResultSuccess(
120                         mAppSearchSessionShim.put(
121                                 new PutDocumentsRequest.Builder()
122                                         .addGenericDocuments(emailDocument)
123                                         .build()));
124                 return true;
125             } catch (Exception e) {
126                 Log.e(TAG, "Failed to index globally searchable document.", e);
127             }
128             return false;
129         }
130 
131         @Override
indexNotGloballySearchableDocument()132         public boolean indexNotGloballySearchableDocument() {
133             try {
134                 mAppSearchSessionShim
135                         .setSchema(
136                                 new SetSchemaRequest.Builder()
137                                         .addSchemas(AppSearchEmail.SCHEMA)
138                                         .setSchemaTypeDisplayedBySystem(
139                                                 AppSearchEmail.SCHEMA_TYPE, /*displayed=*/ false)
140                                         .build())
141                         .get();
142 
143                 AppSearchEmail emailDocument =
144                         new AppSearchEmail.Builder("namespace", "id1")
145                                 .setFrom("from@example.com")
146                                 .setTo("to1@example.com", "to2@example.com")
147                                 .setSubject("subject")
148                                 .setBody("this is the body of the email")
149                                 .build();
150                 checkIsBatchResultSuccess(
151                         mAppSearchSessionShim.put(
152                                 new PutDocumentsRequest.Builder()
153                                         .addGenericDocuments(emailDocument)
154                                         .build()));
155                 return true;
156             } catch (Exception e) {
157                 Log.e(TAG, "Failed to index not-globally searchable document.", e);
158             }
159             return false;
160         }
161 
clearData()162         public boolean clearData() {
163             try {
164                 // Force override with empty schema will clear all previous schemas and their
165                 // documents.
166                 mAppSearchSessionShim
167                         .setSchema(new SetSchemaRequest.Builder().setForceOverride(true).build())
168                         .get();
169                 return true;
170             } catch (Exception e) {
171                 Log.e(TAG, "Failed to clear data.", e);
172             }
173             return false;
174         }
175     }
176 }
177