1 /* 2 * Copyright (C) 2009 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.sdkuilib.internal.repository; 18 19 import com.android.prefs.AndroidLocation; 20 import com.android.prefs.AndroidLocation.AndroidLocationException; 21 import com.android.sdklib.ISdkLog; 22 23 import org.eclipse.jface.dialogs.MessageDialog; 24 25 import java.io.File; 26 import java.io.FileInputStream; 27 import java.io.FileNotFoundException; 28 import java.io.FileOutputStream; 29 import java.io.IOException; 30 import java.util.Properties; 31 32 /** 33 * Controller class to get settings values. Settings are kept in-memory. 34 * Users of this class must first load the settings before changing them and save 35 * them when modified. 36 * <p/> 37 * Settings are enumerated by constants in {@link ISettingsPage}. 38 */ 39 public class SettingsController { 40 41 private static final String SETTINGS_FILENAME = "androidtool.cfg"; //$NON-NLS-1$ 42 43 private final Properties mProperties = new Properties(); 44 45 private ISettingsPage mSettingsPage; 46 47 private final UpdaterData mUpdaterData; 48 49 public SettingsController(UpdaterData updaterData) { 50 mUpdaterData = updaterData; 51 } 52 53 //--- Access to settings ------------ 54 55 /** 56 * Returns the value of the {@link ISettingsPage#KEY_FORCE_HTTP} setting. 57 * @see ISettingsPage#KEY_FORCE_HTTP 58 */ 59 public boolean getForceHttp() { 60 return Boolean.parseBoolean(mProperties.getProperty(ISettingsPage.KEY_FORCE_HTTP)); 61 } 62 63 /** 64 * Returns the value of the {@link ISettingsPage#KEY_ASK_ADB_RESTART} setting. 65 * @see ISettingsPage#KEY_ASK_ADB_RESTART 66 */ 67 public boolean getAskBeforeAdbRestart() { 68 String value = mProperties.getProperty(ISettingsPage.KEY_ASK_ADB_RESTART); 69 if (value == null) { 70 return true; 71 } 72 return Boolean.parseBoolean(value); 73 } 74 75 /** 76 * Returns the value of the {@link ISettingsPage#KEY_SHOW_UPDATE_ONLY} setting. 77 * @see ISettingsPage#KEY_SHOW_UPDATE_ONLY 78 */ 79 public boolean getShowUpdateOnly() { 80 String value = mProperties.getProperty(ISettingsPage.KEY_SHOW_UPDATE_ONLY); 81 if (value == null) { 82 return true; 83 } 84 return Boolean.parseBoolean(value); 85 } 86 87 /** 88 * Sets the value of the {@link ISettingsPage#KEY_SHOW_UPDATE_ONLY} setting. 89 * @param enabled True if only compatible update items should be shown. 90 * @see ISettingsPage#KEY_SHOW_UPDATE_ONLY 91 */ 92 public void setShowUpdateOnly(boolean enabled) { 93 setSetting(ISettingsPage.KEY_SHOW_UPDATE_ONLY, enabled); 94 } 95 96 /** 97 * Returns the value of the {@link ISettingsPage#KEY_MONITOR_DENSITY} setting 98 * @see ISettingsPage#KEY_MONITOR_DENSITY 99 */ 100 public int getMonitorDensity() { 101 String value = mProperties.getProperty(ISettingsPage.KEY_MONITOR_DENSITY, null); 102 if (value == null) { 103 return -1; 104 } 105 106 try { 107 return Integer.parseInt(value); 108 } catch (NumberFormatException e) { 109 return -1; 110 } 111 } 112 113 /** 114 * Sets the value of the {@link ISettingsPage#KEY_MONITOR_DENSITY} setting. 115 * @param density the density of the monitor 116 * @see ISettingsPage#KEY_MONITOR_DENSITY 117 */ 118 public void setMonitorDensity(int density) { 119 mProperties.setProperty(ISettingsPage.KEY_MONITOR_DENSITY, Integer.toString(density)); 120 } 121 122 /** 123 * Internal helper to set a boolean setting. 124 */ 125 private void setSetting(String key, boolean value) { 126 mProperties.setProperty(key, Boolean.toString(value)); 127 } 128 129 //--- Controller methods ------------- 130 131 /** 132 * Associate the given {@link ISettingsPage} with this {@link SettingsController}. 133 * 134 * This loads the current properties into the setting page UI. 135 * It then associates the SettingsChanged callback with this controller. 136 */ 137 public void setSettingsPage(ISettingsPage settingsPage) { 138 139 mSettingsPage = settingsPage; 140 mSettingsPage.loadSettings(mProperties); 141 142 settingsPage.setOnSettingsChanged(new ISettingsPage.SettingsChangedCallback() { 143 public void onSettingsChanged(ISettingsPage page) { 144 SettingsController.this.onSettingsChanged(); 145 } 146 }); 147 } 148 149 /** 150 * Load settings from the settings file. 151 */ 152 public void loadSettings() { 153 FileInputStream fis = null; 154 String path = null; 155 try { 156 String folder = AndroidLocation.getFolder(); 157 File f = new File(folder, SETTINGS_FILENAME); 158 path = f.getPath(); 159 if (f.exists()) { 160 fis = new FileInputStream(f); 161 162 mProperties.load(fis); 163 164 // Properly reformat some settings to enforce their default value when missing. 165 setShowUpdateOnly(getShowUpdateOnly()); 166 setSetting(ISettingsPage.KEY_ASK_ADB_RESTART, getAskBeforeAdbRestart()); 167 } 168 169 } catch (Exception e) { 170 ISdkLog log = mUpdaterData.getSdkLog(); 171 if (log != null) { 172 log.error(e, "Failed to load settings from .android folder. Path is '%1$s'.", path); 173 } 174 } finally { 175 if (fis != null) { 176 try { 177 fis.close(); 178 } catch (IOException e) { 179 } 180 } 181 } 182 } 183 184 /** 185 * Saves settings to the settings file. 186 */ 187 public void saveSettings() { 188 189 FileOutputStream fos = null; 190 String path = null; 191 try { 192 String folder = AndroidLocation.getFolder(); 193 File f = new File(folder, SETTINGS_FILENAME); 194 path = f.getPath(); 195 196 fos = new FileOutputStream(f); 197 198 mProperties.store( fos, "## Settings for Android Tool"); //$NON-NLS-1$ 199 200 } catch (Exception e) { 201 ISdkLog log = mUpdaterData.getSdkLog(); 202 203 if (log != null) { 204 log.error(e, "Failed to save settings at '%1$s'", path); 205 } 206 207 // This is important enough that we want to really nag the user about it 208 String reason = null; 209 210 if (e instanceof FileNotFoundException) { 211 reason = "File not found"; 212 } else if (e instanceof AndroidLocationException) { 213 reason = ".android folder not found, please define ANDROID_SDK_HOME"; 214 } else if (e.getMessage() != null) { 215 reason = String.format("%1$s: %2$s", e.getClass().getSimpleName(), e.getMessage()); 216 } else { 217 reason = e.getClass().getName(); 218 } 219 220 MessageDialog.openInformation(mUpdaterData.getWindowShell(), 221 "SDK Manager Settings", 222 String.format( 223 "The Android SDK and AVD Manager failed to save its settings (%1$s) at %2$s", 224 reason, path)); 225 226 } finally { 227 if (fos != null) { 228 try { 229 fos.close(); 230 } catch (IOException e) { 231 } 232 } 233 } 234 } 235 236 /** 237 * When settings have changed: retrieve the new settings, apply them and save them. 238 * 239 * This updates Java system properties for the HTTP proxy. 240 */ 241 private void onSettingsChanged() { 242 if (mSettingsPage == null) { 243 return; 244 } 245 246 String oldHttpsSetting = mProperties.getProperty(ISettingsPage.KEY_FORCE_HTTP, 247 Boolean.FALSE.toString()); 248 249 mSettingsPage.retrieveSettings(mProperties); 250 applySettings(); 251 saveSettings(); 252 253 String newHttpsSetting = mProperties.getProperty(ISettingsPage.KEY_FORCE_HTTP, 254 Boolean.FALSE.toString()); 255 if (!newHttpsSetting.equals(oldHttpsSetting)) { 256 // In case the HTTP/HTTPS setting change, force sources to be reloaded 257 // (this only refreshes sources that the user has already tried to open.) 258 mUpdaterData.refreshSources(false /*forceFetching*/); 259 } 260 } 261 262 /** 263 * Applies the current settings. 264 */ 265 public void applySettings() { 266 Properties props = System.getProperties(); 267 props.setProperty(ISettingsPage.KEY_HTTP_PROXY_HOST, 268 mProperties.getProperty(ISettingsPage.KEY_HTTP_PROXY_HOST, "")); //$NON-NLS-1$ 269 props.setProperty(ISettingsPage.KEY_HTTP_PROXY_PORT, 270 mProperties.getProperty(ISettingsPage.KEY_HTTP_PROXY_PORT, "")); //$NON-NLS-1$ 271 } 272 273 } 274