From 19ce6b15e3aca347483f2a76ba5a463ab9a5c9c9 Mon Sep 17 00:00:00 2001 From: weijiaxu Date: Mon, 14 May 2018 14:18:57 -0700 Subject: Refactor simulator menu and add portal package for adding simulator service later. Bug: 79488174 Test: build dialer. PiperOrigin-RevId: 196565757 Change-Id: Ic87c2640d856e25f3d7d476edc4fa36588351ece --- .../simulator/impl/SimulatorConferenceCreator.java | 9 +- .../dialer/simulator/impl/SimulatorImpl.java | 3 +- .../dialer/simulator/impl/SimulatorMainMenu.java | 216 --------------------- .../simulator/impl/SimulatorMissedCallCreator.java | 4 +- .../simulator/impl/SimulatorNotifications.java | 62 ------ .../dialer/simulator/impl/SimulatorRttCall.java | 18 +- .../simulator/impl/SimulatorSimCallManager.java | 4 +- .../dialer/simulator/impl/SimulatorSubMenu.java | 100 ---------- .../dialer/simulator/impl/SimulatorUtils.java | 204 +++++++++++++++++++ .../dialer/simulator/impl/SimulatorVideoCall.java | 32 +-- .../dialer/simulator/impl/SimulatorVoiceCall.java | 66 +------ .../simulator/portal/SimulatorMainPortal.java | 198 +++++++++++++++++++ .../dialer/simulator/portal/SimulatorMenu.java | 76 ++++++++ .../portal/SimulatorPortalEntryGroup.java | 45 +++++ 14 files changed, 555 insertions(+), 482 deletions(-) delete mode 100644 java/com/android/dialer/simulator/impl/SimulatorMainMenu.java delete mode 100644 java/com/android/dialer/simulator/impl/SimulatorNotifications.java delete mode 100644 java/com/android/dialer/simulator/impl/SimulatorSubMenu.java create mode 100644 java/com/android/dialer/simulator/impl/SimulatorUtils.java create mode 100644 java/com/android/dialer/simulator/portal/SimulatorMainPortal.java create mode 100644 java/com/android/dialer/simulator/portal/SimulatorMenu.java create mode 100644 java/com/android/dialer/simulator/portal/SimulatorPortalEntryGroup.java (limited to 'java/com/android/dialer/simulator') diff --git a/java/com/android/dialer/simulator/impl/SimulatorConferenceCreator.java b/java/com/android/dialer/simulator/impl/SimulatorConferenceCreator.java index 81a3d30de..8e794f051 100644 --- a/java/com/android/dialer/simulator/impl/SimulatorConferenceCreator.java +++ b/java/com/android/dialer/simulator/impl/SimulatorConferenceCreator.java @@ -32,7 +32,7 @@ import java.util.ArrayList; import java.util.Locale; /** Creates a conference with a given number of participants. */ -final class SimulatorConferenceCreator +public final class SimulatorConferenceCreator implements SimulatorConnectionService.Listener, SimulatorConnection.Listener, SimulatorConference.Listener { @@ -53,7 +53,12 @@ final class SimulatorConferenceCreator simulatorConnectionsBank = SimulatorComponent.get(context).getSimulatorConnectionsBank(); } - void start(int callCount) { + /** + * Starts to create certain number of calls to form a conference call. + * + * @param callCount the number of calls in conference to create. + */ + public void start(int callCount) { onNewIncomingConnectionEnabled = true; SimulatorConnectionService.addListener(this); if (conferenceType == Simulator.CONFERENCE_TYPE_VOLTE) { diff --git a/java/com/android/dialer/simulator/impl/SimulatorImpl.java b/java/com/android/dialer/simulator/impl/SimulatorImpl.java index c8b8af92e..44f8e118b 100644 --- a/java/com/android/dialer/simulator/impl/SimulatorImpl.java +++ b/java/com/android/dialer/simulator/impl/SimulatorImpl.java @@ -22,6 +22,7 @@ import com.android.dialer.buildtype.BuildType; import com.android.dialer.buildtype.BuildType.Type; import com.android.dialer.common.LogUtil; import com.android.dialer.simulator.Simulator; +import com.android.dialer.simulator.portal.SimulatorMainPortal; import javax.inject.Inject; /** The entry point for the simulator feature. */ @@ -39,7 +40,7 @@ final class SimulatorImpl implements Simulator { @Override public ActionProvider getActionProvider(AppCompatActivity activity) { - return SimulatorMainMenu.getActionProvider(activity); + return new SimulatorMainPortal(activity).getActionProvider(); } @Override diff --git a/java/com/android/dialer/simulator/impl/SimulatorMainMenu.java b/java/com/android/dialer/simulator/impl/SimulatorMainMenu.java deleted file mode 100644 index ba2b55802..000000000 --- a/java/com/android/dialer/simulator/impl/SimulatorMainMenu.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.dialer.simulator.impl; - -import android.content.Context; -import android.content.Intent; -import android.provider.VoicemailContract; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.v7.app.AppCompatActivity; -import android.view.ActionProvider; -import com.android.dialer.common.concurrent.DialerExecutor.Worker; -import com.android.dialer.common.concurrent.DialerExecutorComponent; -import com.android.dialer.databasepopulator.BlockedBumberPopulator; -import com.android.dialer.databasepopulator.CallLogPopulator; -import com.android.dialer.databasepopulator.ContactsPopulator; -import com.android.dialer.databasepopulator.VoicemailPopulator; -import com.android.dialer.enrichedcall.simulator.EnrichedCallSimulatorActivity; -import com.android.dialer.persistentlog.PersistentLogger; -import com.android.dialer.preferredsim.PreferredSimFallbackContract; -import com.android.dialer.simulator.SimulatorComponent; - -/** Implements the top level simulator menu. */ -final class SimulatorMainMenu { - - static ActionProvider getActionProvider(@NonNull AppCompatActivity activity) { - SimulatorSubMenu simulatorSubMenu = new SimulatorSubMenu(activity.getApplicationContext()); - simulatorSubMenu - .addItem("Voice call", SimulatorVoiceCall.getActionProvider(activity)) - .addItem("Rtt call", SimulatorRttCall.getActionProvider(activity.getApplicationContext())) - .addItem( - "IMS video", SimulatorVideoCall.getActionProvider(activity.getApplicationContext())) - .addItem( - "Notifications", - SimulatorNotifications.getActionProvider(activity.getApplicationContext())) - .addItem("Populate database", () -> populateDatabase(activity.getApplicationContext())) - .addItem("Populate voicemail", () -> populateVoicemail(activity.getApplicationContext())) - .addItem( - "Fast populate database", () -> fastPopulateDatabase(activity.getApplicationContext())) - .addItem( - "Fast populate voicemail database", - () -> populateVoicemailFast(activity.getApplicationContext())) - .addItem("Clean database", () -> cleanDatabase(activity.getApplicationContext())) - .addItem("clear preferred SIM", () -> clearPreferredSim(activity.getApplicationContext())) - .addItem("Sync voicemail", () -> syncVoicemail(activity.getApplicationContext())) - .addItem("Share persistent log", () -> sharePersistentLog(activity.getApplicationContext())) - .addItem( - "Enriched call simulator", - () -> - activity.startActivity( - EnrichedCallSimulatorActivity.newIntent(activity.getApplicationContext()))) - .addItem( - "Enable simulator mode", - () -> { - SimulatorComponent.get(activity.getApplicationContext()) - .getSimulator() - .enableSimulatorMode(); - SimulatorSimCallManager.register(activity.getApplicationContext()); - }) - .addItem( - "Disable simulator mode", - () -> { - SimulatorComponent.get(activity.getApplicationContext()) - .getSimulator() - .disableSimulatorMode(); - SimulatorSimCallManager.unregister(activity.getApplicationContext()); - }); - return simulatorSubMenu; - } - - private static void populateDatabase(@NonNull Context context) { - DialerExecutorComponent.get(context) - .dialerExecutorFactory() - .createNonUiTaskBuilder(new PopulateDatabaseWorker()) - .build() - .executeSerial(new PopulateDatabaseWorkerInput(context, false)); - } - - private static void populateVoicemail(@NonNull Context context) { - DialerExecutorComponent.get(context) - .dialerExecutorFactory() - .createNonUiTaskBuilder(new PopulateVoicemailWorker()) - .build() - .executeSerial(new PopulateDatabaseWorkerInput(context, false)); - } - - private static void populateVoicemailFast(@NonNull Context context) { - DialerExecutorComponent.get(context) - .dialerExecutorFactory() - .createNonUiTaskBuilder(new PopulateVoicemailWorker()) - .build() - .executeSerial(new PopulateDatabaseWorkerInput(context, true)); - } - - private static class PopulateVoicemailWorker - implements Worker { - @Nullable - @Override - public Void doInBackground(PopulateDatabaseWorkerInput input) { - VoicemailPopulator.populateVoicemail(input.context, input.fastMode); - return null; - } - } - - private static void fastPopulateDatabase(@NonNull Context context) { - DialerExecutorComponent.get(context) - .dialerExecutorFactory() - .createNonUiTaskBuilder(new PopulateDatabaseWorker()) - .build() - .executeSerial(new PopulateDatabaseWorkerInput(context, true)); - } - - private static void cleanDatabase(@NonNull Context context) { - DialerExecutorComponent.get(context) - .dialerExecutorFactory() - .createNonUiTaskBuilder(new CleanDatabaseWorker()) - .build() - .executeSerial(context); - } - - private static void clearPreferredSim(Context context) { - DialerExecutorComponent.get(context) - .dialerExecutorFactory() - .createNonUiTaskBuilder(new ClearPreferredSimWorker()) - .build() - .executeSerial(context); - } - - private static void syncVoicemail(@NonNull Context context) { - Intent intent = new Intent(VoicemailContract.ACTION_SYNC_VOICEMAIL); - context.sendBroadcast(intent); - } - - private static void sharePersistentLog(@NonNull Context context) { - DialerExecutorComponent.get(context) - .dialerExecutorFactory() - .createNonUiTaskBuilder(new ShareLogWorker()) - .onSuccess( - (String log) -> { - Intent intent = new Intent(Intent.ACTION_SEND); - intent.setType("text/plain"); - intent.putExtra(Intent.EXTRA_TEXT, log); - if (intent.resolveActivity(context.getPackageManager()) != null) { - context.startActivity(intent); - } - }) - .build() - .executeSerial(null); - } - - private SimulatorMainMenu() {} - - private static class PopulateDatabaseWorker implements Worker { - @Nullable - @Override - public Void doInBackground(PopulateDatabaseWorkerInput input) { - ContactsPopulator.populateContacts(input.context, input.fastMode); - CallLogPopulator.populateCallLog(input.context, false, input.fastMode); - VoicemailPopulator.populateVoicemail(input.context, input.fastMode); - return null; - } - } - - private static class CleanDatabaseWorker implements Worker { - @Nullable - @Override - public Void doInBackground(Context context) { - ContactsPopulator.deleteAllContacts(context); - CallLogPopulator.deleteAllCallLog(context); - VoicemailPopulator.deleteAllVoicemail(context); - BlockedBumberPopulator.deleteBlockedNumbers(context); - return null; - } - } - - private static class ClearPreferredSimWorker implements Worker { - @Nullable - @Override - public Void doInBackground(Context context) { - context.getContentResolver().delete(PreferredSimFallbackContract.CONTENT_URI, null, null); - return null; - } - } - - private static class ShareLogWorker implements Worker { - @Nullable - @Override - public String doInBackground(Void unused) { - return PersistentLogger.dumpLogToString(); - } - } - - private static class PopulateDatabaseWorkerInput { - Context context; - boolean fastMode; - - PopulateDatabaseWorkerInput(Context context, boolean fastMode) { - this.context = context; - this.fastMode = fastMode; - } - } -} diff --git a/java/com/android/dialer/simulator/impl/SimulatorMissedCallCreator.java b/java/com/android/dialer/simulator/impl/SimulatorMissedCallCreator.java index b8556156b..52d7352ac 100644 --- a/java/com/android/dialer/simulator/impl/SimulatorMissedCallCreator.java +++ b/java/com/android/dialer/simulator/impl/SimulatorMissedCallCreator.java @@ -30,14 +30,14 @@ import com.android.dialer.common.concurrent.ThreadUtil; * notifications instead of writing to the call log directly. This makes the simulator behave more * like the real application. */ -final class SimulatorMissedCallCreator implements SimulatorConnectionService.Listener { +public final class SimulatorMissedCallCreator implements SimulatorConnectionService.Listener { private static final String EXTRA_CALL_COUNT = "call_count"; private static final String EXTRA_IS_MISSED_CALL_CONNECTION = "is_missed_call_connection"; private static final int DISCONNECT_DELAY_MILLIS = 1000; private final Context context; - SimulatorMissedCallCreator(@NonNull Context context) { + public SimulatorMissedCallCreator(@NonNull Context context) { this.context = Assert.isNotNull(context); } diff --git a/java/com/android/dialer/simulator/impl/SimulatorNotifications.java b/java/com/android/dialer/simulator/impl/SimulatorNotifications.java deleted file mode 100644 index bd17b7ff8..000000000 --- a/java/com/android/dialer/simulator/impl/SimulatorNotifications.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.dialer.simulator.impl; - -import android.content.ContentValues; -import android.content.Context; -import android.provider.VoicemailContract.Voicemails; -import android.support.annotation.NonNull; -import android.view.ActionProvider; -import com.android.dialer.common.LogUtil; -import com.android.dialer.databasepopulator.VoicemailPopulator; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; - -/** Implements the simulator submenu. */ -final class SimulatorNotifications { - private static final int NOTIFICATION_COUNT = 12; - - static ActionProvider getActionProvider(@NonNull Context context) { - return new SimulatorSubMenu(context) - .addItem( - "Missed calls", () -> new SimulatorMissedCallCreator(context).start(NOTIFICATION_COUNT)) - .addItem("Voicemails", () -> addVoicemailNotifications(context)); - } - - private static void addVoicemailNotifications(@NonNull Context context) { - LogUtil.enterBlock("SimulatorNotifications.addVoicemailNotifications"); - List voicemails = new ArrayList<>(); - for (int i = NOTIFICATION_COUNT; i > 0; i--) { - VoicemailPopulator.Voicemail voicemail = - VoicemailPopulator.Voicemail.builder() - .setPhoneNumber(String.format("+%d", i)) - .setTranscription(String.format("Short transcript %d", i)) - .setDurationSeconds(60) - .setIsRead(false) - .setPhoneAccountComponentName("") - .setTimeMillis(System.currentTimeMillis() - TimeUnit.HOURS.toMillis(i)) - .build(); - voicemails.add(voicemail.getAsContentValues(context)); - } - context - .getContentResolver() - .bulkInsert( - Voicemails.buildSourceUri(context.getPackageName()), - voicemails.toArray(new ContentValues[voicemails.size()])); - } -} diff --git a/java/com/android/dialer/simulator/impl/SimulatorRttCall.java b/java/com/android/dialer/simulator/impl/SimulatorRttCall.java index 352b9e4ef..afd897775 100644 --- a/java/com/android/dialer/simulator/impl/SimulatorRttCall.java +++ b/java/com/android/dialer/simulator/impl/SimulatorRttCall.java @@ -21,7 +21,6 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.telecom.Connection; import android.telecom.DisconnectCause; -import android.view.ActionProvider; import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.ThreadUtil; @@ -29,28 +28,21 @@ import com.android.dialer.simulator.Simulator; import com.android.dialer.simulator.Simulator.Event; /** Entry point in the simulator to create voice calls. */ -final class SimulatorRttCall +public final class SimulatorRttCall implements SimulatorConnectionService.Listener, SimulatorConnection.Listener { @NonNull private final Context context; @Nullable private String connectionTag; private RttChatBot rttChatBot; - static ActionProvider getActionProvider(@NonNull Context context) { - return new SimulatorSubMenu(context) - .addItem("Incoming call", () -> new SimulatorRttCall(context).addNewIncomingCall(false)) - .addItem("Outgoing call", () -> new SimulatorRttCall(context).addNewOutgoingCall()) - .addItem("Emergency call", () -> new SimulatorRttCall(context).addNewEmergencyCall()); - } - - private SimulatorRttCall(@NonNull Context context) { + public SimulatorRttCall(@NonNull Context context) { this.context = Assert.isNotNull(context); SimulatorConnectionService.addListener(this); SimulatorConnectionService.addListener( new SimulatorConferenceCreator(context, Simulator.CONFERENCE_TYPE_GSM)); } - private void addNewIncomingCall(boolean isSpam) { + public void addNewIncomingCall(boolean isSpam) { String callerId = isSpam ? "+1-661-778-3020" /* Blacklisted custom spam number */ @@ -60,14 +52,14 @@ final class SimulatorRttCall context, callerId, SimulatorSimCallManager.CALL_TYPE_RTT); } - private void addNewOutgoingCall() { + public void addNewOutgoingCall() { String callerId = "+55-31-2128-6800"; // Brazil office. connectionTag = SimulatorSimCallManager.addNewOutgoingCall( context, callerId, SimulatorSimCallManager.CALL_TYPE_RTT); } - private void addNewEmergencyCall() { + public void addNewEmergencyCall() { String callerId = "911"; connectionTag = SimulatorSimCallManager.addNewIncomingCall( diff --git a/java/com/android/dialer/simulator/impl/SimulatorSimCallManager.java b/java/com/android/dialer/simulator/impl/SimulatorSimCallManager.java index c56afb21f..0296ace4b 100644 --- a/java/com/android/dialer/simulator/impl/SimulatorSimCallManager.java +++ b/java/com/android/dialer/simulator/impl/SimulatorSimCallManager.java @@ -64,7 +64,7 @@ public class SimulatorSimCallManager { private static final String EXTRA_CONNECTION_TAG = "connection_tag"; private static final String EXTRA_CONNECTION_CALL_TYPE = "connection_call_type"; - static void register(@NonNull Context context) { + public static void register(@NonNull Context context) { LogUtil.enterBlock("SimulatorSimCallManager.register"); Assert.isNotNull(context); StrictModeUtils.bypass( @@ -75,7 +75,7 @@ public class SimulatorSimCallManager { }); } - static void unregister(@NonNull Context context) { + public static void unregister(@NonNull Context context) { LogUtil.enterBlock("SimulatorSimCallManager.unregister"); Assert.isNotNull(context); StrictModeUtils.bypass( diff --git a/java/com/android/dialer/simulator/impl/SimulatorSubMenu.java b/java/com/android/dialer/simulator/impl/SimulatorSubMenu.java deleted file mode 100644 index 64a2e7265..000000000 --- a/java/com/android/dialer/simulator/impl/SimulatorSubMenu.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.dialer.simulator.impl; - -import android.content.Context; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.view.ActionProvider; -import android.view.MenuItem; -import android.view.SubMenu; -import android.view.View; -import com.android.dialer.common.Assert; -import java.util.ArrayList; -import java.util.List; - -/** Makes it easier to create submenus in the simulator. */ -final class SimulatorSubMenu extends ActionProvider { - List items = new ArrayList<>(); - - SimulatorSubMenu(@NonNull Context context) { - super(Assert.isNotNull(context)); - } - - SimulatorSubMenu addItem(@NonNull String title, @NonNull Runnable clickHandler) { - items.add(new Item(title, clickHandler)); - return this; - } - - SimulatorSubMenu addItem(@NonNull String title, @NonNull ActionProvider actionProvider) { - items.add(new Item(title, actionProvider)); - return this; - } - - @Override - public View onCreateActionView() { - return null; - } - - @Override - public View onCreateActionView(MenuItem forItem) { - return null; - } - - @Override - public boolean hasSubMenu() { - return true; - } - - @Override - public void onPrepareSubMenu(SubMenu subMenu) { - super.onPrepareSubMenu(subMenu); - subMenu.clear(); - - for (Item item : items) { - if (item.clickHandler != null) { - subMenu - .add(item.title) - .setOnMenuItemClickListener( - (i) -> { - item.clickHandler.run(); - return true; - }); - } else { - subMenu.add(item.title).setActionProvider(item.actionProvider); - } - } - } - - private static final class Item { - @NonNull final String title; - @Nullable final Runnable clickHandler; - @Nullable final ActionProvider actionProvider; - - Item(@NonNull String title, @NonNull Runnable clickHandler) { - this.title = Assert.isNotNull(title); - this.clickHandler = Assert.isNotNull(clickHandler); - actionProvider = null; - } - - Item(@NonNull String title, @NonNull ActionProvider actionProvider) { - this.title = Assert.isNotNull(title); - this.clickHandler = null; - this.actionProvider = Assert.isNotNull(actionProvider); - } - } -} diff --git a/java/com/android/dialer/simulator/impl/SimulatorUtils.java b/java/com/android/dialer/simulator/impl/SimulatorUtils.java new file mode 100644 index 000000000..9e46f5aa9 --- /dev/null +++ b/java/com/android/dialer/simulator/impl/SimulatorUtils.java @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.dialer.simulator.impl; + +import android.content.ContentValues; +import android.content.Context; +import android.content.Intent; +import android.provider.VoicemailContract; +import android.provider.VoicemailContract.Voicemails; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import com.android.dialer.common.LogUtil; +import com.android.dialer.common.concurrent.DialerExecutor.Worker; +import com.android.dialer.common.concurrent.DialerExecutorComponent; +import com.android.dialer.databasepopulator.BlockedBumberPopulator; +import com.android.dialer.databasepopulator.CallLogPopulator; +import com.android.dialer.databasepopulator.ContactsPopulator; +import com.android.dialer.databasepopulator.VoicemailPopulator; +import com.android.dialer.persistentlog.PersistentLogger; +import com.android.dialer.preferredsim.PreferredSimFallbackContract; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.concurrent.TimeUnit; + +/** Contains utilities used often in test workflow. */ +public class SimulatorUtils { + + public static final int NOTIFICATION_COUNT_FEW = 1; + public static final int NOTIFICATION_COUNT = 12; + + /** Populates contacts database with predefined contacts entries. */ + public static void populateDatabase(@NonNull Context context) { + DialerExecutorComponent.get(context) + .dialerExecutorFactory() + .createNonUiTaskBuilder(new PopulateDatabaseWorker()) + .build() + .executeSerial(new PopulateDatabaseWorkerInput(context, false)); + } + + /** Populates voicemail database with predefined voicemail entries. */ + public static void populateVoicemail(@NonNull Context context) { + DialerExecutorComponent.get(context) + .dialerExecutorFactory() + .createNonUiTaskBuilder(new PopulateVoicemailWorker()) + .build() + .executeSerial(new PopulateDatabaseWorkerInput(context, false)); + } + + /** Populates voicemail database with only few predefined voicemail entries. */ + public static void populateVoicemailFast(@NonNull Context context) { + DialerExecutorComponent.get(context) + .dialerExecutorFactory() + .createNonUiTaskBuilder(new PopulateVoicemailWorker()) + .build() + .executeSerial(new PopulateDatabaseWorkerInput(context, true)); + } + + /** Populates contacts database with only few predefined contacts entries. */ + public static void fastPopulateDatabase(@NonNull Context context) { + DialerExecutorComponent.get(context) + .dialerExecutorFactory() + .createNonUiTaskBuilder(new PopulateDatabaseWorker()) + .build() + .executeSerial(new PopulateDatabaseWorkerInput(context, true)); + } + + /** Clean contacts database. */ + public static void cleanDatabase(@NonNull Context context) { + DialerExecutorComponent.get(context) + .dialerExecutorFactory() + .createNonUiTaskBuilder(new CleanDatabaseWorker()) + .build() + .executeSerial(context); + } + + /** Clear preference over sim. */ + public static void clearPreferredSim(Context context) { + DialerExecutorComponent.get(context) + .dialerExecutorFactory() + .createNonUiTaskBuilder(new ClearPreferredSimWorker()) + .build() + .executeSerial(context); + } + + /** Sync voicemail by sending intents to system. */ + public static void syncVoicemail(@NonNull Context context) { + Intent intent = new Intent(VoicemailContract.ACTION_SYNC_VOICEMAIL); + context.sendBroadcast(intent); + } + + public static void sharePersistentLog(@NonNull Context context) { + DialerExecutorComponent.get(context) + .dialerExecutorFactory() + .createNonUiTaskBuilder(new ShareLogWorker()) + .onSuccess( + (String log) -> { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("text/plain"); + intent.putExtra(Intent.EXTRA_TEXT, log); + if (intent.resolveActivity(context.getPackageManager()) != null) { + context.startActivity(intent); + } + }) + .build() + .executeSerial(null); + } + + public static void addVoicemailNotifications(@NonNull Context context, int notificationNum) { + LogUtil.enterBlock("SimulatorNotifications.addVoicemailNotifications"); + List voicemails = new ArrayList<>(); + for (int i = notificationNum; i > 0; i--) { + VoicemailPopulator.Voicemail voicemail = + VoicemailPopulator.Voicemail.builder() + .setPhoneNumber(String.format(Locale.ENGLISH, "+%d", i)) + .setTranscription(String.format(Locale.ENGLISH, "Short transcript %d", i)) + .setDurationSeconds(60) + .setIsRead(false) + .setPhoneAccountComponentName("") + .setTimeMillis(System.currentTimeMillis() - TimeUnit.HOURS.toMillis(i)) + .build(); + voicemails.add(voicemail.getAsContentValues(context)); + } + context + .getContentResolver() + .bulkInsert( + Voicemails.buildSourceUri(context.getPackageName()), + voicemails.toArray(new ContentValues[voicemails.size()])); + } + + private static class PopulateVoicemailWorker + implements Worker { + @Nullable + @Override + public Void doInBackground(PopulateDatabaseWorkerInput input) { + VoicemailPopulator.populateVoicemail(input.context, input.fastMode); + return null; + } + } + + private static class PopulateDatabaseWorker implements Worker { + @Nullable + @Override + public Void doInBackground(PopulateDatabaseWorkerInput input) { + ContactsPopulator.populateContacts(input.context, input.fastMode); + CallLogPopulator.populateCallLog(input.context, false, input.fastMode); + VoicemailPopulator.populateVoicemail(input.context, input.fastMode); + return null; + } + } + + private static class CleanDatabaseWorker implements Worker { + @Nullable + @Override + public Void doInBackground(Context context) { + ContactsPopulator.deleteAllContacts(context); + CallLogPopulator.deleteAllCallLog(context); + VoicemailPopulator.deleteAllVoicemail(context); + BlockedBumberPopulator.deleteBlockedNumbers(context); + return null; + } + } + + private static class ClearPreferredSimWorker implements Worker { + @Nullable + @Override + public Void doInBackground(Context context) { + context.getContentResolver().delete(PreferredSimFallbackContract.CONTENT_URI, null, null); + return null; + } + } + + private static class ShareLogWorker implements Worker { + @Nullable + @Override + public String doInBackground(Void unused) { + return PersistentLogger.dumpLogToString(); + } + } + + private static class PopulateDatabaseWorkerInput { + Context context; + boolean fastMode; + + PopulateDatabaseWorkerInput(Context context, boolean fastMode) { + this.context = context; + this.fastMode = fastMode; + } + } +} diff --git a/java/com/android/dialer/simulator/impl/SimulatorVideoCall.java b/java/com/android/dialer/simulator/impl/SimulatorVideoCall.java index 0bb56f1f9..c7c92e7b9 100644 --- a/java/com/android/dialer/simulator/impl/SimulatorVideoCall.java +++ b/java/com/android/dialer/simulator/impl/SimulatorVideoCall.java @@ -23,8 +23,6 @@ import android.support.annotation.Nullable; import android.telecom.Connection; import android.telecom.DisconnectCause; import android.telecom.TelecomManager; -import android.telecom.VideoProfile; -import android.view.ActionProvider; import android.widget.Toast; import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; @@ -32,36 +30,14 @@ import com.android.dialer.common.concurrent.ThreadUtil; import com.android.dialer.simulator.Simulator.Event; /** Entry point in the simulator to create video calls. */ -final class SimulatorVideoCall +public final class SimulatorVideoCall implements SimulatorConnectionService.Listener, SimulatorConnection.Listener { @NonNull private final Context context; private final int initialVideoCapability; private final int initialVideoState; @Nullable private String connectionTag; - static ActionProvider getActionProvider(@NonNull Context context) { - return new SimulatorSubMenu(context) - .addItem( - "Incoming one way", - () -> - new SimulatorVideoCall(context, VideoProfile.STATE_RX_ENABLED).addNewIncomingCall()) - .addItem( - "Incoming two way", - () -> - new SimulatorVideoCall(context, VideoProfile.STATE_BIDIRECTIONAL) - .addNewIncomingCall()) - .addItem( - "Outgoing one way", - () -> - new SimulatorVideoCall(context, VideoProfile.STATE_TX_ENABLED).addNewOutgoingCall()) - .addItem( - "Outgoing two way", - () -> - new SimulatorVideoCall(context, VideoProfile.STATE_BIDIRECTIONAL) - .addNewOutgoingCall()); - } - - private SimulatorVideoCall(@NonNull Context context, int initialVideoState) { + public SimulatorVideoCall(@NonNull Context context, int initialVideoState) { this.context = Assert.isNotNull(context); this.initialVideoCapability = Connection.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL @@ -70,7 +46,7 @@ final class SimulatorVideoCall SimulatorConnectionService.addListener(this); } - private void addNewIncomingCall() { + public void addNewIncomingCall() { if (!isVideoAccountEnabled()) { showVideoAccountSettings(); return; @@ -81,7 +57,7 @@ final class SimulatorVideoCall context, callerId, SimulatorSimCallManager.CALL_TYPE_VIDEO); } - private void addNewOutgoingCall() { + public void addNewOutgoingCall() { if (!isVideoAccountEnabled()) { showVideoAccountSettings(); return; diff --git a/java/com/android/dialer/simulator/impl/SimulatorVoiceCall.java b/java/com/android/dialer/simulator/impl/SimulatorVoiceCall.java index e59cddd51..a9f332e4a 100644 --- a/java/com/android/dialer/simulator/impl/SimulatorVoiceCall.java +++ b/java/com/android/dialer/simulator/impl/SimulatorVoiceCall.java @@ -24,7 +24,6 @@ import android.support.v7.app.AppCompatActivity; import android.telecom.Connection; import android.telecom.Connection.RttModifyStatus; import android.telecom.DisconnectCause; -import android.view.ActionProvider; import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.DialerExecutorComponent; @@ -37,58 +36,13 @@ import com.android.dialer.simulator.SimulatorComponent; import com.android.dialer.simulator.SimulatorEnrichedCall; /** Entry point in the simulator to create voice calls. */ -final class SimulatorVoiceCall +public final class SimulatorVoiceCall implements SimulatorConnectionService.Listener, SimulatorConnection.Listener { @NonNull private final Context context; @Nullable private String connectionTag; private final SimulatorEnrichedCall simulatorEnrichedCall; - static ActionProvider getActionProvider(@NonNull AppCompatActivity activity) { - return new SimulatorSubMenu(activity.getApplicationContext()) - .addItem( - "Incoming call", - () -> new SimulatorVoiceCall(activity.getApplicationContext()).addNewIncomingCall()) - .addItem( - "Outgoing call", - () -> new SimulatorVoiceCall(activity.getApplicationContext()).addNewOutgoingCall()) - .addItem( - "Customized incoming call", - () -> - new SimulatorVoiceCall(activity.getApplicationContext()) - .addNewIncomingCall(activity)) - .addItem( - "Customized outgoing call", - () -> - new SimulatorVoiceCall(activity.getApplicationContext()) - .addNewOutgoingCall(activity)) - .addItem( - "Incoming enriched call", - () -> new SimulatorVoiceCall(activity.getApplicationContext()).incomingEnrichedCall()) - .addItem( - "Outgoing enriched call", - () -> new SimulatorVoiceCall(activity.getApplicationContext()).outgoingEnrichedCall()) - .addItem( - "Spam incoming call", - () -> new SimulatorVoiceCall(activity.getApplicationContext()).addSpamIncomingCall()) - .addItem( - "Emergency call back", - () -> - new SimulatorVoiceCall(activity.getApplicationContext()).addNewEmergencyCallBack()) - .addItem( - "GSM conference", - () -> - new SimulatorConferenceCreator( - activity.getApplicationContext(), Simulator.CONFERENCE_TYPE_GSM) - .start(5)) - .addItem( - "VoLTE conference", - () -> - new SimulatorConferenceCreator( - activity.getApplicationContext(), Simulator.CONFERENCE_TYPE_VOLTE) - .start(5)); - } - - private SimulatorVoiceCall(@NonNull Context context) { + public SimulatorVoiceCall(@NonNull Context context) { this.context = Assert.isNotNull(context); simulatorEnrichedCall = SimulatorComponent.get(context).getSimulatorEnrichedCall(); SimulatorConnectionService.addListener(this); @@ -96,7 +50,7 @@ final class SimulatorVoiceCall new SimulatorConferenceCreator(context, Simulator.CONFERENCE_TYPE_GSM)); } - private void incomingEnrichedCall() { + public void incomingEnrichedCall() { simulatorEnrichedCall .setupIncomingEnrichedCall(Simulator.ENRICHED_CALL_INCOMING_NUMBER) .addListener( @@ -113,7 +67,7 @@ final class SimulatorVoiceCall DialerExecutorComponent.get(context).uiExecutor()); } - private void outgoingEnrichedCall() { + public void outgoingEnrichedCall() { getEnrichedCallManager().registerStateChangedListener(simulatorEnrichedCall); simulatorEnrichedCall .setupOutgoingEnrichedCall(Simulator.ENRICHED_CALL_OUTGOING_NUMBER) @@ -131,14 +85,14 @@ final class SimulatorVoiceCall DialerExecutorComponent.get(context).uiExecutor()); } - private void addNewIncomingCall() { + public void addNewIncomingCall() { String callerId = "+44 (0) 20 7031 3000" /* Google London office */; connectionTag = SimulatorSimCallManager.addNewIncomingCall( context, callerId, SimulatorSimCallManager.CALL_TYPE_VOICE); } - private void addNewIncomingCall(AppCompatActivity activity) { + public void addNewIncomingCall(AppCompatActivity activity) { SimulatorDialogFragment.newInstance( (callerId, callerIdPresentation) -> { Bundle extras = new Bundle(); @@ -150,14 +104,14 @@ final class SimulatorVoiceCall .show(activity.getSupportFragmentManager(), "SimulatorDialog"); } - private void addNewOutgoingCall() { + public void addNewOutgoingCall() { String callerId = "+55-31-2128-6800"; // Brazil office. connectionTag = SimulatorSimCallManager.addNewOutgoingCall( context, callerId, SimulatorSimCallManager.CALL_TYPE_VOICE); } - private void addNewOutgoingCall(AppCompatActivity activity) { + public void addNewOutgoingCall(AppCompatActivity activity) { SimulatorDialogFragment.newInstance( (callerId, callerIdPresentation) -> { Bundle extras = new Bundle(); @@ -169,14 +123,14 @@ final class SimulatorVoiceCall .show(activity.getSupportFragmentManager(), "SimulatorDialog"); } - private void addSpamIncomingCall() { + public void addSpamIncomingCall() { String callerId = "+1-661-778-3020"; /* Blacklisted custom spam number */ connectionTag = SimulatorSimCallManager.addNewIncomingCall( context, callerId, SimulatorSimCallManager.CALL_TYPE_VOICE); } - private void addNewEmergencyCallBack() { + public void addNewEmergencyCallBack() { String callerId = "911"; connectionTag = SimulatorSimCallManager.addNewIncomingCall( diff --git a/java/com/android/dialer/simulator/portal/SimulatorMainPortal.java b/java/com/android/dialer/simulator/portal/SimulatorMainPortal.java new file mode 100644 index 000000000..fdec2a540 --- /dev/null +++ b/java/com/android/dialer/simulator/portal/SimulatorMainPortal.java @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.dialer.simulator.portal; + +import android.content.Context; +import android.support.v7.app.AppCompatActivity; +import android.telecom.VideoProfile; +import android.view.ActionProvider; +import com.android.dialer.enrichedcall.simulator.EnrichedCallSimulatorActivity; +import com.android.dialer.simulator.Simulator; +import com.android.dialer.simulator.SimulatorComponent; +import com.android.dialer.simulator.impl.SimulatorConferenceCreator; +import com.android.dialer.simulator.impl.SimulatorMissedCallCreator; +import com.android.dialer.simulator.impl.SimulatorRttCall; +import com.android.dialer.simulator.impl.SimulatorSimCallManager; +import com.android.dialer.simulator.impl.SimulatorUtils; +import com.android.dialer.simulator.impl.SimulatorVideoCall; +import com.android.dialer.simulator.impl.SimulatorVoiceCall; +import com.google.common.collect.ImmutableMap; + +/** Implements the top level simulator menu. */ +public final class SimulatorMainPortal { + + private final Context context; + private final AppCompatActivity activity; + private SimulatorPortalEntryGroup simulatorMainPortal; + + public SimulatorMainPortal(AppCompatActivity activity) { + this.activity = activity; + this.context = activity.getApplicationContext(); + buildMainPortal(); + } + + private void buildMainPortal() { + this.simulatorMainPortal = + SimulatorPortalEntryGroup.builder() + .setMethods( + ImmutableMap.builder() + .put("Populate database", () -> SimulatorUtils.populateDatabase(context)) + .put("Populate voicemail", () -> SimulatorUtils.populateVoicemail(context)) + .put( + "Fast Populate database", + () -> SimulatorUtils.fastPopulateDatabase(context)) + .put( + "Fast populate voicemail database", + () -> SimulatorUtils.populateVoicemailFast(context)) + .put("Clean database", () -> SimulatorUtils.cleanDatabase(context)) + .put("clear preferred SIM", () -> SimulatorUtils.clearPreferredSim(context)) + .put("Sync voicemail", () -> SimulatorUtils.syncVoicemail(context)) + .put("Share persistent log", () -> SimulatorUtils.sharePersistentLog(context)) + .put( + "Enriched call simulator", + () -> + context.startActivity(EnrichedCallSimulatorActivity.newIntent(context))) + .put( + "Enable simulator mode", + () -> { + SimulatorComponent.get(context).getSimulator().enableSimulatorMode(); + SimulatorSimCallManager.register(context); + }) + .put( + "Disable simulator mode", + () -> { + SimulatorComponent.get(context).getSimulator().disableSimulatorMode(); + SimulatorSimCallManager.unregister(context); + }) + .build()) + .setSubPortals( + ImmutableMap.of( + "VoiceCall", + buildSimulatorVoiceCallPortal(), + "VideoCall", + buildSimulatorVideoCallPortal(), + "RttCall", + buildSimulatorRttCallPortal(), + "Notifications", + buildSimulatorNotificationsPortal())) + .build(); + } + + public SimulatorPortalEntryGroup buildSimulatorVoiceCallPortal() { + return SimulatorPortalEntryGroup.builder() + .setMethods( + ImmutableMap.builder() + .put("Incoming call", () -> new SimulatorVoiceCall(context).addNewIncomingCall()) + .put("Outgoing call", () -> new SimulatorVoiceCall(context).addNewOutgoingCall()) + .put( + "Customized incoming call", + () -> new SimulatorVoiceCall(context).addNewIncomingCall(activity)) + .put( + "Customized outgoing call", + () -> new SimulatorVoiceCall(context).addNewOutgoingCall(activity)) + .put( + "Incoming enriched call", + () -> new SimulatorVoiceCall(context).incomingEnrichedCall()) + .put( + "Outgoing enriched call", + () -> new SimulatorVoiceCall(context).outgoingEnrichedCall()) + .put( + "Spam incoming call", + () -> new SimulatorVoiceCall(context).addSpamIncomingCall()) + .put( + "Emergency call back", + () -> new SimulatorVoiceCall(context).addNewEmergencyCallBack()) + .put( + "GSM conference", + () -> + new SimulatorConferenceCreator(context, Simulator.CONFERENCE_TYPE_GSM) + .start(5)) + .put( + "VoLTE conference", + () -> + new SimulatorConferenceCreator(context, Simulator.CONFERENCE_TYPE_VOLTE) + .start(5)) + .build()) + .build(); + } + + private SimulatorPortalEntryGroup buildSimulatorVideoCallPortal() { + return SimulatorPortalEntryGroup.builder() + .setMethods( + ImmutableMap.builder() + .put( + "Incoming one way", + () -> + new SimulatorVideoCall(context, VideoProfile.STATE_RX_ENABLED) + .addNewIncomingCall()) + .put( + "Incoming two way", + () -> + new SimulatorVideoCall(context, VideoProfile.STATE_BIDIRECTIONAL) + .addNewIncomingCall()) + .put( + "Outgoing one way", + () -> + new SimulatorVideoCall(context, VideoProfile.STATE_TX_ENABLED) + .addNewOutgoingCall()) + .put( + "Outgoing two way", + () -> + new SimulatorVideoCall(context, VideoProfile.STATE_BIDIRECTIONAL) + .addNewOutgoingCall()) + .build()) + .build(); + } + + private SimulatorPortalEntryGroup buildSimulatorRttCallPortal() { + return SimulatorPortalEntryGroup.builder() + .setMethods( + ImmutableMap.builder() + .put("Incoming call", () -> new SimulatorRttCall(context).addNewIncomingCall(false)) + .put("Outgoing call", () -> new SimulatorRttCall(context).addNewOutgoingCall()) + .put("Emergency call", () -> new SimulatorRttCall(context).addNewEmergencyCall()) + .build()) + .build(); + } + + private SimulatorPortalEntryGroup buildSimulatorNotificationsPortal() { + return SimulatorPortalEntryGroup.builder() + .setMethods( + ImmutableMap.builder() + .put( + "Missed calls", + () -> + new SimulatorMissedCallCreator(context) + .start(SimulatorUtils.NOTIFICATION_COUNT)) + .put( + "Missed calls (few)", + () -> + new SimulatorMissedCallCreator(context) + .start(SimulatorUtils.NOTIFICATION_COUNT_FEW)) + .put( + "Voicemails", + () -> + SimulatorUtils.addVoicemailNotifications( + context, SimulatorUtils.NOTIFICATION_COUNT)) + .build()) + .build(); + } + + public ActionProvider getActionProvider() { + return new SimulatorMenu(context, simulatorMainPortal); + } +} diff --git a/java/com/android/dialer/simulator/portal/SimulatorMenu.java b/java/com/android/dialer/simulator/portal/SimulatorMenu.java new file mode 100644 index 000000000..01fd4aa0e --- /dev/null +++ b/java/com/android/dialer/simulator/portal/SimulatorMenu.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.dialer.simulator.portal; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.view.ActionProvider; +import android.view.MenuItem; +import android.view.SubMenu; +import android.view.View; +import com.android.dialer.common.Assert; +import java.util.Map.Entry; + +/** Makes option menu for simulator. */ +public final class SimulatorMenu extends ActionProvider { + + SimulatorPortalEntryGroup portal; + + Context context; + + public SimulatorMenu(@NonNull Context context, SimulatorPortalEntryGroup portal) { + super(Assert.isNotNull(context)); + this.context = context; + this.portal = portal; + } + + @Override + public View onCreateActionView() { + return null; + } + + @Override + public View onCreateActionView(MenuItem forItem) { + return null; + } + + @Override + public boolean hasSubMenu() { + return true; + } + + @Override + public void onPrepareSubMenu(SubMenu subMenu) { + super.onPrepareSubMenu(subMenu); + subMenu.clear(); + + for (Entry subPortal : portal.subPortals().entrySet()) { + subMenu + .add(subPortal.getKey()) + .setActionProvider(new SimulatorMenu(context, subPortal.getValue())); + } + for (Entry method : portal.methods().entrySet()) { + subMenu + .add(method.getKey()) + .setOnMenuItemClickListener( + (i) -> { + method.getValue().run(); + return true; + }); + } + } +} diff --git a/java/com/android/dialer/simulator/portal/SimulatorPortalEntryGroup.java b/java/com/android/dialer/simulator/portal/SimulatorPortalEntryGroup.java new file mode 100644 index 000000000..30a248cb1 --- /dev/null +++ b/java/com/android/dialer/simulator/portal/SimulatorPortalEntryGroup.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.dialer.simulator.portal; + +import com.google.auto.value.AutoValue; +import com.google.common.collect.ImmutableMap; +import java.util.Collections; +import java.util.Map; + +/** Represents a portal that receives requests from either UI or IPC. */ +@AutoValue +public abstract class SimulatorPortalEntryGroup { + abstract ImmutableMap methods(); + + abstract ImmutableMap subPortals(); + + static Builder builder() { + return new AutoValue_SimulatorPortalEntryGroup.Builder() + .setMethods(Collections.emptyMap()) + .setSubPortals(Collections.emptyMap()); + } + + @AutoValue.Builder + abstract static class Builder { + abstract Builder setMethods(Map value); + + abstract Builder setSubPortals(Map value); + + abstract SimulatorPortalEntryGroup build(); + } +} -- cgit v1.2.3