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