• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     /** The currently associated {@link ISettingsPage}. Can be null. */
46     private ISettingsPage mSettingsPage;
47 
48     private final UpdaterData mUpdaterData;
49 
SettingsController(UpdaterData updaterData)50     public SettingsController(UpdaterData updaterData) {
51         mUpdaterData = updaterData;
52     }
53 
54     //--- Access to settings ------------
55 
56     /**
57      * Returns the value of the {@link ISettingsPage#KEY_FORCE_HTTP} setting.
58      *
59      * @see ISettingsPage#KEY_FORCE_HTTP
60      */
getForceHttp()61     public boolean getForceHttp() {
62         return Boolean.parseBoolean(mProperties.getProperty(ISettingsPage.KEY_FORCE_HTTP));
63     }
64 
65     /**
66      * Returns the value of the {@link ISettingsPage#KEY_ASK_ADB_RESTART} setting.
67      *
68      * @see ISettingsPage#KEY_ASK_ADB_RESTART
69      */
getAskBeforeAdbRestart()70     public boolean getAskBeforeAdbRestart() {
71         String value = mProperties.getProperty(ISettingsPage.KEY_ASK_ADB_RESTART);
72         if (value == null) {
73             return true;
74         }
75         return Boolean.parseBoolean(value);
76     }
77 
78     /**
79      * Returns the value of the {@link ISettingsPage#KEY_SHOW_UPDATE_ONLY} setting.
80      *
81      * @see ISettingsPage#KEY_SHOW_UPDATE_ONLY
82      */
getShowUpdateOnly()83     public boolean getShowUpdateOnly() {
84         String value = mProperties.getProperty(ISettingsPage.KEY_SHOW_UPDATE_ONLY);
85         if (value == null) {
86             return true;
87         }
88         return Boolean.parseBoolean(value);
89     }
90 
91     /**
92      * Sets the value of the {@link ISettingsPage#KEY_SHOW_UPDATE_ONLY} setting.
93      *
94      * @param enabled True if only compatible non-obsolete update items should be shown.
95      * @see ISettingsPage#KEY_SHOW_UPDATE_ONLY
96      */
setShowUpdateOnly(boolean enabled)97     public void setShowUpdateOnly(boolean enabled) {
98         setSetting(ISettingsPage.KEY_SHOW_UPDATE_ONLY, enabled);
99     }
100 
101     /**
102      * Returns the value of the {@link ISettingsPage#KEY_MONITOR_DENSITY} setting
103      * @see ISettingsPage#KEY_MONITOR_DENSITY
104      */
getMonitorDensity()105     public int getMonitorDensity() {
106         String value = mProperties.getProperty(ISettingsPage.KEY_MONITOR_DENSITY, null);
107         if (value == null) {
108             return -1;
109         }
110 
111         try {
112             return Integer.parseInt(value);
113         } catch (NumberFormatException e) {
114             return -1;
115         }
116     }
117 
118     /**
119      * Sets the value of the {@link ISettingsPage#KEY_MONITOR_DENSITY} setting.
120      *
121      * @param density the density of the monitor
122      * @see ISettingsPage#KEY_MONITOR_DENSITY
123      */
setMonitorDensity(int density)124     public void setMonitorDensity(int density) {
125         mProperties.setProperty(ISettingsPage.KEY_MONITOR_DENSITY, Integer.toString(density));
126     }
127 
128     /**
129      * Internal helper to set a boolean setting.
130      */
setSetting(String key, boolean value)131     void setSetting(String key, boolean value) {
132         mProperties.setProperty(key, Boolean.toString(value));
133     }
134 
135     //--- Controller methods -------------
136 
137     /**
138      * Associate the given {@link ISettingsPage} with this {@link SettingsController}.
139      * <p/>
140      * This loads the current properties into the setting page UI.
141      * It then associates the SettingsChanged callback with this controller.
142      * <p/>
143      * If the setting page given is null, it will be unlinked from controller.
144      *
145      * @param settingsPage An {@link ISettingsPage} to associate with the controller.
146      */
setSettingsPage(ISettingsPage settingsPage)147     public void setSettingsPage(ISettingsPage settingsPage) {
148         mSettingsPage = settingsPage;
149 
150         if (settingsPage != null) {
151             settingsPage.loadSettings(mProperties);
152 
153             settingsPage.setOnSettingsChanged(new ISettingsPage.SettingsChangedCallback() {
154                 public void onSettingsChanged(ISettingsPage page) {
155                     SettingsController.this.onSettingsChanged();
156                 }
157             });
158         }
159     }
160 
161     /**
162      * Load settings from the settings file.
163      */
loadSettings()164     public void loadSettings() {
165         FileInputStream fis = null;
166         String path = null;
167         try {
168             String folder = AndroidLocation.getFolder();
169             File f = new File(folder, SETTINGS_FILENAME);
170             path = f.getPath();
171             if (f.exists()) {
172                 fis = new FileInputStream(f);
173 
174                 mProperties.load(fis);
175 
176                 // Properly reformat some settings to enforce their default value when missing.
177                 setShowUpdateOnly(getShowUpdateOnly());
178                 setSetting(ISettingsPage.KEY_ASK_ADB_RESTART, getAskBeforeAdbRestart());
179             }
180 
181         } catch (Exception e) {
182             ISdkLog log = mUpdaterData.getSdkLog();
183             if (log != null) {
184                 log.error(e, "Failed to load settings from .android folder. Path is '%1$s'.", path);
185             }
186         } finally {
187             if (fis != null) {
188                 try {
189                     fis.close();
190                 } catch (IOException e) {
191                 }
192             }
193         }
194     }
195 
196     /**
197      * Saves settings to the settings file.
198      */
saveSettings()199     public void saveSettings() {
200 
201         FileOutputStream fos = null;
202         String path = null;
203         try {
204             String folder = AndroidLocation.getFolder();
205             File f = new File(folder, SETTINGS_FILENAME);
206             path = f.getPath();
207 
208             fos = new FileOutputStream(f);
209 
210             mProperties.store( fos, "## Settings for Android Tool");  //$NON-NLS-1$
211 
212         } catch (Exception e) {
213             ISdkLog log = mUpdaterData.getSdkLog();
214 
215             if (log != null) {
216                 log.error(e, "Failed to save settings at '%1$s'", path);
217             }
218 
219             // This is important enough that we want to really nag the user about it
220             String reason = null;
221 
222             if (e instanceof FileNotFoundException) {
223                 reason = "File not found";
224             } else if (e instanceof AndroidLocationException) {
225                 reason = ".android folder not found, please define ANDROID_SDK_HOME";
226             } else if (e.getMessage() != null) {
227                 reason = String.format("%1$s: %2$s", e.getClass().getSimpleName(), e.getMessage());
228             } else {
229                 reason = e.getClass().getName();
230             }
231 
232             MessageDialog.openInformation(mUpdaterData.getWindowShell(),
233                     "SDK Manager Settings",
234                     String.format(
235                         "The Android SDK and AVD Manager failed to save its settings (%1$s) at %2$s",
236                         reason, path));
237 
238         } finally {
239             if (fos != null) {
240                 try {
241                     fos.close();
242                 } catch (IOException e) {
243                 }
244             }
245         }
246     }
247 
248     /**
249      * When settings have changed: retrieve the new settings, apply them and save them.
250      *
251      * This updates Java system properties for the HTTP proxy.
252      */
onSettingsChanged()253     private void onSettingsChanged() {
254         if (mSettingsPage == null) {
255             return;
256         }
257 
258         String oldHttpsSetting = mProperties.getProperty(ISettingsPage.KEY_FORCE_HTTP,
259                 Boolean.FALSE.toString());
260 
261         mSettingsPage.retrieveSettings(mProperties);
262         applySettings();
263         saveSettings();
264 
265         String newHttpsSetting = mProperties.getProperty(ISettingsPage.KEY_FORCE_HTTP,
266                 Boolean.FALSE.toString());
267         if (!newHttpsSetting.equals(oldHttpsSetting)) {
268             // In case the HTTP/HTTPS setting changes, force sources to be reloaded
269             // (this only refreshes sources that the user has already tried to open.)
270             mUpdaterData.refreshSources(false /*forceFetching*/);
271         }
272     }
273 
274     /**
275      * Applies the current settings.
276      */
applySettings()277     public void applySettings() {
278         Properties props = System.getProperties();
279 
280         // Get the configured HTTP proxy settings
281         String proxyHost = mProperties.getProperty(ISettingsPage.KEY_HTTP_PROXY_HOST,
282                 ""); //$NON-NLS-1$
283         String proxyPort = mProperties.getProperty(ISettingsPage.KEY_HTTP_PROXY_PORT,
284                 ""); //$NON-NLS-1$
285 
286         // Set both the HTTP and HTTPS proxy system properties.
287         // The system property constants can be found in the Java SE documentation at
288         // http://download.oracle.com/javase/6/docs/technotes/guides/net/proxies.html
289         final String JAVA_PROP_HTTP_PROXY_HOST =  "http.proxyHost";      //$NON-NLS-1$
290         final String JAVA_PROP_HTTP_PROXY_PORT =  "http.proxyPort";      //$NON-NLS-1$
291         final String JAVA_PROP_HTTPS_PROXY_HOST = "https.proxyHost";     //$NON-NLS-1$
292         final String JAVA_PROP_HTTPS_PROXY_PORT = "https.proxyPort";     //$NON-NLS-1$
293 
294         props.setProperty(JAVA_PROP_HTTP_PROXY_HOST,  proxyHost);
295         props.setProperty(JAVA_PROP_HTTP_PROXY_PORT,  proxyPort);
296         props.setProperty(JAVA_PROP_HTTPS_PROXY_HOST, proxyHost);
297         props.setProperty(JAVA_PROP_HTTPS_PROXY_PORT, proxyPort);
298      }
299 
300 }
301