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.car.voicecontrol;
17 
18 import android.content.Context;
19 import android.content.Intent;
20 import android.os.Bundle;
21 import android.util.Log;
22 
23 import androidx.annotation.NonNull;
24 import androidx.appcompat.app.AppCompatActivity;
25 import androidx.preference.ListPreference;
26 import androidx.preference.Preference;
27 
28 import com.android.car.ui.preference.PreferenceFragment;
29 
30 import java.lang.ref.WeakReference;
31 
32 /**
33  * Sample voice interaction service settings activity
34  */
35 public class SettingsActivity extends AppCompatActivity {
36     private static final String TAG = "Mica.SettingsActivity";
37     private InteractionServiceClient mInteractionService;
38     private TextToSpeech mTextToSpeech;
39 
40     @Override
onCreate(Bundle savedInstanceState)41     protected void onCreate(Bundle savedInstanceState) {
42         super.onCreate(savedInstanceState);
43 
44         mInteractionService = new InteractionServiceClient(this) {
45             @Override
46             void onConnected() {
47                 // Display the fragment as the main content.
48                 if (savedInstanceState == null) {
49                     getSupportFragmentManager()
50                             .beginTransaction()
51                             .replace(android.R.id.content, new SettingsFragment(), "settings")
52                             .commitNow();
53                 }
54             }
55 
56             @Override
57             void onSetupChanged() {
58                 SettingsFragment fragment = (SettingsFragment) getSupportFragmentManager()
59                         .findFragmentByTag("settings");
60                 if (fragment != null) {
61                     fragment.updateSignInState();
62                 }
63             }
64         };
65         mInteractionService.connect();
66         mTextToSpeech = new TextToSpeechImpl(this, new TextToSpeech.Listener() {
67             @Override
68             public void onReady(TextToSpeech tts) {
69                 SettingsFragment fragment = (SettingsFragment) getSupportFragmentManager()
70                         .findFragmentByTag("settings");
71                 if (fragment != null) {
72                     fragment.updateVoices();
73                 }
74             }
75         });
76     }
77 
78     @Override
onDestroy()79     public void onDestroy() {
80         mInteractionService.disconnect();
81         mTextToSpeech.destroy();
82         super.onDestroy();
83     }
84 
85     /**
86      * {@link PreferenceFragment} implementation for voice interaction service settings
87      */
88     public static class SettingsFragment extends PreferenceFragment {
89         private WeakReference<SettingsActivity> mActivity;
90 
91         @Override
onAttach(@onNull Context context)92         public void onAttach(@NonNull Context context) {
93             super.onAttach(context);
94             mActivity = new WeakReference<>((SettingsActivity) context);
95         }
96 
97         @Override
onDetach()98         public void onDetach() {
99             mActivity = null;
100             super.onDetach();
101         }
102 
103         @Override
onCreatePreferences(Bundle savedInstanceState, String rootKey)104         public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
105             setPreferencesFromResource(R.xml.preferences, rootKey);
106             updateSignInState();
107             updateVoices();
108         }
109 
updateSignInState()110         private void updateSignInState() {
111             boolean isSignedIn = mActivity.get().mInteractionService.hasUsername();
112             Log.d(TAG, "updateSignInState: signed in " + isSignedIn);
113             Preference signInOutButton = getPreferenceManager().findPreference("sign_in_out");
114             assert signInOutButton != null;
115             signInOutButton.setTitle(getString(isSignedIn
116                     ? R.string.preference_sign_out
117                     : R.string.preference_sign_in));
118             signInOutButton.setSummary(getString(isSignedIn
119                     ? R.string.preference_sign_out
120                     : R.string.preference_sign_in));
121             signInOutButton.setOnPreferenceClickListener(p -> {
122                 if (mActivity.get().mInteractionService.hasUsername()) {
123                     mActivity.get().mInteractionService.setUsername(null);
124                 } else {
125                     Intent intent = new Intent(getContext(), SignInActivity.class);
126                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
127                     startActivity(intent);
128                 }
129                 return true;
130             });
131         }
132 
updateVoices()133         private void updateVoices() {
134             ListPreference pref = getPreferenceManager()
135                     .findPreference(PreferencesController.PREF_KEY_VOICE);
136             String[] voices = mActivity.get().mTextToSpeech.getVoices().toArray(new String[0]);
137             pref.setEntries(voices);
138             pref.setEntryValues(voices);
139             pref.setOnPreferenceChangeListener((p, value) -> {
140                 mActivity.get().mInteractionService.setVoice((String) value);
141                 return true;
142             });
143         }
144     }
145 }
146