1 /*
2  * Copyright (C) 2018 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.dialer.simulator.impl;
18 
19 import android.content.ContentValues;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.provider.VoicemailContract;
23 import android.provider.VoicemailContract.Voicemails;
24 import android.support.annotation.NonNull;
25 import android.support.annotation.Nullable;
26 import com.android.dialer.common.LogUtil;
27 import com.android.dialer.common.concurrent.DialerExecutor.Worker;
28 import com.android.dialer.common.concurrent.DialerExecutorComponent;
29 import com.android.dialer.databasepopulator.BlockedBumberPopulator;
30 import com.android.dialer.databasepopulator.CallLogPopulator;
31 import com.android.dialer.databasepopulator.ContactsPopulator;
32 import com.android.dialer.databasepopulator.VoicemailPopulator;
33 import com.android.dialer.persistentlog.PersistentLogger;
34 import com.android.dialer.preferredsim.PreferredSimFallbackContract;
35 import java.util.ArrayList;
36 import java.util.List;
37 import java.util.Locale;
38 import java.util.concurrent.TimeUnit;
39 
40 /** Contains utilities used often in test workflow. */
41 public class SimulatorUtils {
42 
43   public static final int NOTIFICATION_COUNT_FEW = 1;
44   public static final int NOTIFICATION_COUNT = 12;
45 
46   /** Populates contacts database with predefined contacts entries. */
populateDatabase(@onNull Context context)47   public static void populateDatabase(@NonNull Context context) {
48     DialerExecutorComponent.get(context)
49         .dialerExecutorFactory()
50         .createNonUiTaskBuilder(new PopulateDatabaseWorker())
51         .build()
52         .executeSerial(new PopulateDatabaseWorkerInput(context, false));
53   }
54 
55   /** Populates voicemail database with predefined voicemail entries. */
populateVoicemail(@onNull Context context)56   public static void populateVoicemail(@NonNull Context context) {
57     DialerExecutorComponent.get(context)
58         .dialerExecutorFactory()
59         .createNonUiTaskBuilder(new PopulateVoicemailWorker())
60         .build()
61         .executeSerial(new PopulateDatabaseWorkerInput(context, false));
62   }
63 
64   /** Populates voicemail database with only few predefined voicemail entries. */
populateVoicemailFast(@onNull Context context)65   public static void populateVoicemailFast(@NonNull Context context) {
66     DialerExecutorComponent.get(context)
67         .dialerExecutorFactory()
68         .createNonUiTaskBuilder(new PopulateVoicemailWorker())
69         .build()
70         .executeSerial(new PopulateDatabaseWorkerInput(context, true));
71   }
72 
73   /** Populates contacts database with only few predefined contacts entries. */
fastPopulateDatabase(@onNull Context context)74   public static void fastPopulateDatabase(@NonNull Context context) {
75     DialerExecutorComponent.get(context)
76         .dialerExecutorFactory()
77         .createNonUiTaskBuilder(new PopulateDatabaseWorker())
78         .build()
79         .executeSerial(new PopulateDatabaseWorkerInput(context, true));
80   }
81 
82   /** Clean contacts database. */
cleanDatabase(@onNull Context context)83   public static void cleanDatabase(@NonNull Context context) {
84     DialerExecutorComponent.get(context)
85         .dialerExecutorFactory()
86         .createNonUiTaskBuilder(new CleanDatabaseWorker())
87         .build()
88         .executeSerial(context);
89   }
90 
91   /** Clear preference over sim. */
clearPreferredSim(Context context)92   public static void clearPreferredSim(Context context) {
93     DialerExecutorComponent.get(context)
94         .dialerExecutorFactory()
95         .createNonUiTaskBuilder(new ClearPreferredSimWorker())
96         .build()
97         .executeSerial(context);
98   }
99 
100   /** Sync voicemail by sending intents to system. */
syncVoicemail(@onNull Context context)101   public static void syncVoicemail(@NonNull Context context) {
102     Intent intent = new Intent(VoicemailContract.ACTION_SYNC_VOICEMAIL);
103     context.sendBroadcast(intent);
104   }
105 
sharePersistentLog(@onNull Context context)106   public static void sharePersistentLog(@NonNull Context context) {
107     DialerExecutorComponent.get(context)
108         .dialerExecutorFactory()
109         .createNonUiTaskBuilder(new ShareLogWorker())
110         .onSuccess(
111             (String log) -> {
112               Intent intent = new Intent(Intent.ACTION_SEND);
113               intent.setType("text/plain");
114               intent.putExtra(Intent.EXTRA_TEXT, log);
115               if (intent.resolveActivity(context.getPackageManager()) != null) {
116                 context.startActivity(intent);
117               }
118             })
119         .build()
120         .executeSerial(null);
121   }
122 
addVoicemailNotifications(@onNull Context context, int notificationNum)123   public static void addVoicemailNotifications(@NonNull Context context, int notificationNum) {
124     LogUtil.enterBlock("SimulatorNotifications.addVoicemailNotifications");
125     List<ContentValues> voicemails = new ArrayList<>();
126     for (int i = notificationNum; i > 0; i--) {
127       VoicemailPopulator.Voicemail voicemail =
128           VoicemailPopulator.Voicemail.builder()
129               .setPhoneNumber(String.format(Locale.ENGLISH, "+%d", i))
130               .setTranscription(String.format(Locale.ENGLISH, "Short transcript %d", i))
131               .setDurationSeconds(60)
132               .setIsRead(false)
133               .setPhoneAccountComponentName("")
134               .setTimeMillis(System.currentTimeMillis() - TimeUnit.HOURS.toMillis(i))
135               .build();
136       voicemails.add(voicemail.getAsContentValues(context));
137     }
138     context
139         .getContentResolver()
140         .bulkInsert(
141             Voicemails.buildSourceUri(context.getPackageName()),
142             voicemails.toArray(new ContentValues[voicemails.size()]));
143   }
144 
145   private static class PopulateVoicemailWorker
146       implements Worker<PopulateDatabaseWorkerInput, Void> {
147     @Nullable
148     @Override
doInBackground(PopulateDatabaseWorkerInput input)149     public Void doInBackground(PopulateDatabaseWorkerInput input) {
150       VoicemailPopulator.populateVoicemail(input.context, input.fastMode);
151       return null;
152     }
153   }
154 
155   private static class PopulateDatabaseWorker implements Worker<PopulateDatabaseWorkerInput, Void> {
156     @Nullable
157     @Override
doInBackground(PopulateDatabaseWorkerInput input)158     public Void doInBackground(PopulateDatabaseWorkerInput input) {
159       ContactsPopulator.populateContacts(input.context, input.fastMode);
160       CallLogPopulator.populateCallLog(input.context, false, input.fastMode);
161       VoicemailPopulator.populateVoicemail(input.context, input.fastMode);
162       return null;
163     }
164   }
165 
166   private static class CleanDatabaseWorker implements Worker<Context, Void> {
167     @Nullable
168     @Override
doInBackground(Context context)169     public Void doInBackground(Context context) {
170       ContactsPopulator.deleteAllContacts(context);
171       CallLogPopulator.deleteAllCallLog(context);
172       VoicemailPopulator.deleteAllVoicemail(context);
173       BlockedBumberPopulator.deleteBlockedNumbers(context);
174       return null;
175     }
176   }
177 
178   private static class ClearPreferredSimWorker implements Worker<Context, Void> {
179     @Nullable
180     @Override
doInBackground(Context context)181     public Void doInBackground(Context context) {
182       context.getContentResolver().delete(PreferredSimFallbackContract.CONTENT_URI, null, null);
183       return null;
184     }
185   }
186 
187   private static class ShareLogWorker implements Worker<Void, String> {
188     @Nullable
189     @Override
doInBackground(Void unused)190     public String doInBackground(Void unused) {
191       return PersistentLogger.dumpLogToString();
192     }
193   }
194 
195   private static class PopulateDatabaseWorkerInput {
196     Context context;
197     boolean fastMode;
198 
PopulateDatabaseWorkerInput(Context context, boolean fastMode)199     PopulateDatabaseWorkerInput(Context context, boolean fastMode) {
200       this.context = context;
201       this.fastMode = fastMode;
202     }
203   }
204 }
205