3232
3333public class SettingsActivity extends AppCompatActivity {
3434
35- private String mModelFilePath = "" ;
36- private String mTokenizerFilePath = "" ;
37- private String mDataPath = "" ;
3835 private TextView mBackendTextView ;
3936 private TextView mModelTextView ;
4037 private TextView mTokenizerTextView ;
@@ -43,19 +40,11 @@ public class SettingsActivity extends AppCompatActivity {
4340 private EditText mSystemPromptEditText ;
4441 private EditText mUserPromptEditText ;
4542 private Button mLoadModelButton ;
46- private double mSetTemperature ;
47- private String mSystemPrompt ;
48- private String mUserPrompt ;
49- private BackendType mBackendType ;
50- private ModelType mModelType ;
43+ // mSettingsFields is the single source of truth for all settings
5144 public SettingsFields mSettingsFields ;
5245
53- // Store initial values to detect changes
54- private String mInitialModelFilePath = "" ;
55- private String mInitialTokenizerFilePath = "" ;
56- private String mInitialDataPath = "" ;
57- private BackendType mInitialBackendType ;
58- private ModelType mInitialModelType ;
46+ // Store initial settings to detect changes
47+ private SettingsFields mInitialSettingsFields ;
5948
6049 private DemoSharedPreferences mDemoSharedPreferences ;
6150 public static double TEMPERATURE_MIN_VALUE = 0.0 ;
@@ -145,24 +134,27 @@ private void setupSettings() {
145134 view -> {
146135 setupModelTypeSelectorDialog ();
147136 });
148- if (mModelFilePath != null && !mModelFilePath .isEmpty ()) {
149- mModelTextView .setText (getFilenameFromPath (mModelFilePath ));
137+ String modelFilePath = mSettingsFields .getModelFilePath ();
138+ if (modelFilePath != null && !modelFilePath .isEmpty ()) {
139+ mModelTextView .setText (getFilenameFromPath (modelFilePath ));
150140 }
151- if (mTokenizerFilePath != null && !mTokenizerFilePath .isEmpty ()) {
152- mTokenizerTextView .setText (getFilenameFromPath (mTokenizerFilePath ));
141+ String tokenizerFilePath = mSettingsFields .getTokenizerFilePath ();
142+ if (tokenizerFilePath != null && !tokenizerFilePath .isEmpty ()) {
143+ mTokenizerTextView .setText (getFilenameFromPath (tokenizerFilePath ));
153144 }
154- if (mDataPath != null && !mDataPath .isEmpty ()) {
155- mDataPathTextView .setText (getFilenameFromPath (mDataPath ));
145+ String dataPath = mSettingsFields .getDataPath ();
146+ if (dataPath != null && !dataPath .isEmpty ()) {
147+ mDataPathTextView .setText (getFilenameFromPath (dataPath ));
156148 }
157- mModelType = mSettingsFields .getModelType ();
158- ETLogging .getInstance ().log ("mModelType from settings " + mModelType );
159- if (mModelType != null ) {
160- mModelTypeTextView .setText (mModelType .toString ());
149+ ModelType modelType = mSettingsFields .getModelType ();
150+ ETLogging .getInstance ().log ("mModelType from settings " + modelType );
151+ if (modelType != null ) {
152+ mModelTypeTextView .setText (modelType .toString ());
161153 }
162- mBackendType = mSettingsFields .getBackendType ();
163- ETLogging .getInstance ().log ("mBackendType from settings " + mBackendType );
164- if (mBackendType != null ) {
165- mBackendTextView .setText (mBackendType .toString ());
154+ BackendType backendType = mSettingsFields .getBackendType ();
155+ ETLogging .getInstance ().log ("mBackendType from settings " + backendType );
156+ if (backendType != null ) {
157+ mBackendTextView .setText (backendType .toString ());
166158 setBackendSettingMode ();
167159 }
168160
@@ -226,9 +218,9 @@ private void setupParameterSettings() {
226218 }
227219
228220 private void setupTemperatureSettings () {
229- mSetTemperature = mSettingsFields .getTemperature ();
221+ double temperature = mSettingsFields .getTemperature ();
230222 EditText temperatureEditText = requireViewById (R .id .temperatureEditText );
231- temperatureEditText .setText (String .valueOf (mSetTemperature ));
223+ temperatureEditText .setText (String .valueOf (temperature ));
232224 temperatureEditText .addTextChangedListener (
233225 new TextWatcher () {
234226 @ Override
@@ -239,11 +231,12 @@ public void onTextChanged(CharSequence s, int start, int before, int count) {}
239231
240232 @ Override
241233 public void afterTextChanged (Editable s ) {
242- mSetTemperature = Double .parseDouble (s .toString ());
234+ double newTemperature = Double .parseDouble (s .toString ());
235+ mSettingsFields .saveParameters (newTemperature );
243236 // This is needed because temperature is changed together with model loading
244237 // Once temperature is no longer in LlmModule constructor, we can remove this
245238 mSettingsFields .saveLoadModelAction (true );
246- saveSettings ( );
239+ mDemoSharedPreferences . addSettings ( mSettingsFields );
247240 }
248241 });
249242 }
@@ -254,8 +247,8 @@ private void setupPromptSettings() {
254247 }
255248
256249 private void setupSystemPromptSettings () {
257- mSystemPrompt = mSettingsFields .getSystemPrompt ();
258- mSystemPromptEditText .setText (mSystemPrompt );
250+ String systemPrompt = mSettingsFields .getSystemPrompt ();
251+ mSystemPromptEditText .setText (systemPrompt );
259252 mSystemPromptEditText .addTextChangedListener (
260253 new TextWatcher () {
261254 @ Override
@@ -266,7 +259,7 @@ public void onTextChanged(CharSequence s, int start, int before, int count) {}
266259
267260 @ Override
268261 public void afterTextChanged (Editable s ) {
269- mSystemPrompt = s .toString ();
262+ mSettingsFields . savePrompts ( s .toString (), mSettingsFields . getUserPrompt () );
270263 }
271264 });
272265
@@ -291,8 +284,8 @@ public void onClick(DialogInterface dialog, int whichButton) {
291284 }
292285
293286 private void setupUserPromptSettings () {
294- mUserPrompt = mSettingsFields .getUserPrompt ();
295- mUserPromptEditText .setText (mUserPrompt );
287+ String userPrompt = mSettingsFields .getUserPrompt ();
288+ mUserPromptEditText .setText (userPrompt );
296289 mUserPromptEditText .addTextChangedListener (
297290 new TextWatcher () {
298291 @ Override
@@ -304,7 +297,7 @@ public void onTextChanged(CharSequence s, int start, int before, int count) {}
304297 @ Override
305298 public void afterTextChanged (Editable s ) {
306299 if (isValidUserPrompt (s .toString ())) {
307- mUserPrompt = s .toString ();
300+ mSettingsFields . savePrompts ( mSettingsFields . getSystemPrompt (), s .toString () );
308301 } else {
309302 showInvalidPromptDialog ();
310303 }
@@ -323,7 +316,7 @@ public void afterTextChanged(Editable s) {
323316 new DialogInterface .OnClickListener () {
324317 public void onClick (DialogInterface dialog , int whichButton ) {
325318 // Clear the messageAdapter and sharedPreference
326- mUserPromptEditText .setText (PromptFormat .getUserPromptTemplate (mModelType ));
319+ mUserPromptEditText .setText (PromptFormat .getUserPromptTemplate (mSettingsFields . getModelType () ));
327320 }
328321 })
329322 .setNegativeButton (android .R .string .no , null )
@@ -346,7 +339,7 @@ private void showInvalidPromptDialog() {
346339 .setPositiveButton (
347340 android .R .string .yes ,
348341 (dialog , whichButton ) -> {
349- mUserPromptEditText .setText (PromptFormat .getUserPromptTemplate (mModelType ));
342+ mUserPromptEditText .setText (PromptFormat .getUserPromptTemplate (mSettingsFields . getModelType () ));
350343 })
351344 .setNegativeButton (android .R .string .no , null )
352345 .show ();
@@ -367,7 +360,7 @@ private void setupBackendSelectorDialog() {
367360 -1 ,
368361 (dialog , item ) -> {
369362 mBackendTextView .setText (backendTypes [item ]);
370- mBackendType = BackendType .valueOf (backendTypes [item ]);
363+ mSettingsFields . saveBackendType ( BackendType .valueOf (backendTypes [item ]) );
371364 setBackendSettingMode ();
372365 updateLoadModelButtonState ();
373366 dialog .dismiss ();
@@ -385,8 +378,8 @@ private void setupModelSelectorDialog() {
385378 pteFiles ,
386379 -1 ,
387380 (dialog , item ) -> {
388- mModelFilePath = pteFiles [item ];
389- mModelTextView .setText (getFilenameFromPath (mModelFilePath ));
381+ mSettingsFields . saveModelPath ( pteFiles [item ]) ;
382+ mModelTextView .setText (getFilenameFromPath (pteFiles [ item ] ));
390383 updateLoadModelButtonState ();
391384 dialog .dismiss ();
392385 });
@@ -409,10 +402,10 @@ private void setupDataPathSelectorDialog() {
409402 -1 ,
410403 (dialog , item ) -> {
411404 if (dataPathOptions [item ] != "(unused)" ) {
412- mDataPath = dataPathOptions [item ];
413- mDataPathTextView .setText (getFilenameFromPath (mDataPath ));
405+ mSettingsFields . saveDataPath ( dataPathOptions [item ]) ;
406+ mDataPathTextView .setText (getFilenameFromPath (dataPathOptions [ item ] ));
414407 } else {
415- mDataPath = null ;
408+ mSettingsFields . saveDataPath ( null ) ;
416409 mDataPathTextView .setText (getFilenameFromPath ("no data path selected" ));
417410 }
418411 updateLoadModelButtonState ();
@@ -456,8 +449,9 @@ private void setupModelTypeSelectorDialog() {
456449 -1 ,
457450 (dialog , item ) -> {
458451 mModelTypeTextView .setText (modelTypes [item ]);
459- mModelType = ModelType .valueOf (modelTypes [item ]);
460- mUserPromptEditText .setText (PromptFormat .getUserPromptTemplate (mModelType ));
452+ ModelType selectedModelType = ModelType .valueOf (modelTypes [item ]);
453+ mSettingsFields .saveModelType (selectedModelType );
454+ mUserPromptEditText .setText (PromptFormat .getUserPromptTemplate (selectedModelType ));
461455 updateLoadModelButtonState ();
462456 dialog .dismiss ();
463457 });
@@ -474,8 +468,8 @@ private void setupTokenizerSelectorDialog() {
474468 tokenizerFiles ,
475469 -1 ,
476470 (dialog , item ) -> {
477- mTokenizerFilePath = tokenizerFiles [item ];
478- mTokenizerTextView .setText (getFilenameFromPath (mTokenizerFilePath ));
471+ mSettingsFields . saveTokenizerPath ( tokenizerFiles [item ]) ;
472+ mTokenizerTextView .setText (getFilenameFromPath (tokenizerFiles [ item ] ));
479473 updateLoadModelButtonState ();
480474 dialog .dismiss ();
481475 });
@@ -495,38 +489,27 @@ private String getFilenameFromPath(String uriFilePath) {
495489 }
496490
497491 private void storeInitialSettings () {
498- mInitialModelFilePath = mModelFilePath != null ? mModelFilePath : "" ;
499- mInitialTokenizerFilePath = mTokenizerFilePath != null ? mTokenizerFilePath : "" ;
500- mInitialDataPath = mDataPath != null ? mDataPath : "" ;
501- mInitialBackendType = mBackendType ;
502- mInitialModelType = mModelType ;
492+ mInitialSettingsFields = new SettingsFields (mSettingsFields );
503493 }
504494
505495 private boolean hasSettingsChanged () {
506- String currentModelPath = mModelFilePath != null ? mModelFilePath : "" ;
507- String currentTokenizerPath = mTokenizerFilePath != null ? mTokenizerFilePath : "" ;
508- String currentDataPath = mDataPath != null ? mDataPath : "" ;
509-
510- boolean modelChanged = !currentModelPath .equals (mInitialModelFilePath );
511- boolean tokenizerChanged = !currentTokenizerPath .equals (mInitialTokenizerFilePath );
512- boolean dataPathChanged = !currentDataPath .equals (mInitialDataPath );
513- boolean backendChanged = !java .util .Objects .equals (mBackendType , mInitialBackendType );
514- boolean modelTypeChanged = !java .util .Objects .equals (mModelType , mInitialModelType );
515-
516- return modelChanged || tokenizerChanged || dataPathChanged || backendChanged || modelTypeChanged ;
496+ return !mSettingsFields .equals (mInitialSettingsFields );
517497 }
518498
519499 private void updateLoadModelButtonState () {
520500 // Enable button if settings changed OR if valid pre-filled paths are available
521- boolean hasValidPaths = mModelFilePath != null && !mModelFilePath .isEmpty ()
522- && mTokenizerFilePath != null && !mTokenizerFilePath .isEmpty ();
501+ String modelFilePath = mSettingsFields .getModelFilePath ();
502+ String tokenizerFilePath = mSettingsFields .getTokenizerFilePath ();
503+ boolean hasValidPaths = modelFilePath != null && !modelFilePath .isEmpty ()
504+ && tokenizerFilePath != null && !tokenizerFilePath .isEmpty ();
523505 mLoadModelButton .setEnabled (hasSettingsChanged () || hasValidPaths );
524506 }
525507
526508 private void setBackendSettingMode () {
527- if (mBackendType .equals (BackendType .XNNPACK ) || mBackendType .equals (BackendType .QUALCOMM )) {
509+ BackendType backendType = mSettingsFields .getBackendType ();
510+ if (backendType .equals (BackendType .XNNPACK ) || backendType .equals (BackendType .QUALCOMM )) {
528511 setXNNPACKSettingMode ();
529- } else if (mBackendType .equals (BackendType .MEDIATEK )) {
512+ } else if (backendType .equals (BackendType .MEDIATEK )) {
530513 setMediaTekSettingMode ();
531514 }
532515 }
@@ -546,11 +529,13 @@ private void setMediaTekSettingMode() {
546529 requireViewById (R .id .parametersView ).setVisibility (View .GONE );
547530 requireViewById (R .id .temperatureLayout ).setVisibility (View .GONE );
548531 // For MediaTek, only set default paths if they're empty - preserve existing selections
549- if (mModelFilePath == null || mModelFilePath .isEmpty ()) {
550- mModelFilePath = "/in/mtk/llama/runner" ;
532+ String modelFilePath = mSettingsFields .getModelFilePath ();
533+ if (modelFilePath == null || modelFilePath .isEmpty ()) {
534+ mSettingsFields .saveModelPath ("/in/mtk/llama/runner" );
551535 }
552- if (mTokenizerFilePath == null || mTokenizerFilePath .isEmpty ()) {
553- mTokenizerFilePath = "/in/mtk/llama/runner" ;
536+ String tokenizerFilePath = mSettingsFields .getTokenizerFilePath ();
537+ if (tokenizerFilePath == null || tokenizerFilePath .isEmpty ()) {
538+ mSettingsFields .saveTokenizerPath ("/in/mtk/llama/runner" );
554539 }
555540 }
556541
@@ -559,32 +544,11 @@ private void loadSettings() {
559544 String settingsFieldsJSON = mDemoSharedPreferences .getSettings ();
560545 if (!settingsFieldsJSON .isEmpty ()) {
561546 mSettingsFields = gson .fromJson (settingsFieldsJSON , SettingsFields .class );
562-
563- // Update local variables with loaded values for session persistence
564- mModelFilePath =
565- mSettingsFields .getModelFilePath () != null ? mSettingsFields .getModelFilePath () : "" ;
566- mTokenizerFilePath =
567- mSettingsFields .getTokenizerFilePath () != null
568- ? mSettingsFields .getTokenizerFilePath ()
569- : "" ;
570- mDataPath = mSettingsFields .getDataPath (); // Can be null
571- mSetTemperature = mSettingsFields .getTemperature ();
572- mSystemPrompt =
573- mSettingsFields .getSystemPrompt () != null ? mSettingsFields .getSystemPrompt () : "" ;
574- mUserPrompt = mSettingsFields .getUserPrompt () != null ? mSettingsFields .getUserPrompt () : "" ;
575- mModelType = mSettingsFields .getModelType ();
576- mBackendType = mSettingsFields .getBackendType ();
577547 }
578548 }
579549
580550 private void saveSettings () {
581- mSettingsFields .saveModelPath (mModelFilePath );
582- mSettingsFields .saveTokenizerPath (mTokenizerFilePath );
583- mSettingsFields .saveDataPath (mDataPath );
584- mSettingsFields .saveParameters (mSetTemperature );
585- mSettingsFields .savePrompts (mSystemPrompt , mUserPrompt );
586- mSettingsFields .saveModelType (mModelType );
587- mSettingsFields .saveBackendType (mBackendType );
551+ // All values are now stored directly in mSettingsFields, so just persist to SharedPreferences
588552 mDemoSharedPreferences .addSettings (mSettingsFields );
589553 }
590554
0 commit comments