OSDN Git Service

Remove console selection (Issue #17) - Part II (Settings & Code)
[android-x86/packages-apps-CMFileManager.git] / src / com / cyanogenmod / filemanager / FileManagerApplication.java
1 /*
2  * Copyright (C) 2012 The CyanogenMod 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.cyanogenmod.filemanager;
18
19 import android.app.Application;
20 import android.content.BroadcastReceiver;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.IntentFilter;
24 import android.content.pm.ApplicationInfo;
25 import android.content.pm.PackageManager;
26 import android.util.Log;
27
28 import com.cyanogenmod.filemanager.console.Console;
29 import com.cyanogenmod.filemanager.console.ConsoleAllocException;
30 import com.cyanogenmod.filemanager.console.ConsoleBuilder;
31 import com.cyanogenmod.filemanager.console.ConsoleHolder;
32 import com.cyanogenmod.filemanager.console.shell.PrivilegedConsole;
33 import com.cyanogenmod.filemanager.preferences.AccessMode;
34 import com.cyanogenmod.filemanager.preferences.FileManagerSettings;
35 import com.cyanogenmod.filemanager.preferences.ObjectStringIdentifier;
36 import com.cyanogenmod.filemanager.preferences.Preferences;
37 import com.cyanogenmod.filemanager.util.ExceptionUtil;
38 import com.cyanogenmod.filemanager.util.FileHelper;
39 import com.cyanogenmod.filemanager.util.MimeTypeHelper;
40
41 import java.io.File;
42 import java.io.FileInputStream;
43 import java.util.Properties;
44
45 /**
46  * A class that wraps the information of the application (constants,
47  * identifiers, statics variables, ...).
48  * @hide
49  */
50 public final class FileManagerApplication extends Application {
51
52     private static final String TAG = "FileManagerApplication"; //$NON-NLS-1$
53
54     private static boolean DEBUG = false;
55     private static Properties sSystemProperties;
56
57     /**
58      * A constant that contains the main process name.
59      * @hide
60      */
61     public static final String MAIN_PROCESS = "com.cyanogenmod.filemanager"; //$NON-NLS-1$
62
63     //Static resources
64     private static FileManagerApplication sApp;
65     private static ConsoleHolder sBackgroundConsole;
66
67     private static boolean sIsDebuggable = false;
68     private static boolean sIsDeviceRooted = false;
69
70     private final BroadcastReceiver mOnSettingChangeReceiver = new BroadcastReceiver() {
71         @Override
72         public void onReceive(Context context, Intent intent) {
73             if (intent != null &&
74                 intent.getAction().compareTo(FileManagerSettings.INTENT_SETTING_CHANGED) == 0) {
75
76                 // The settings has changed
77                 String key = intent.getStringExtra(FileManagerSettings.EXTRA_SETTING_CHANGED_KEY);
78                 if (key != null &&
79                     key.compareTo(FileManagerSettings.SETTINGS_SHOW_TRACES.getId()) == 0) {
80
81                     // The debug traces setting has changed. Notify to consoles
82                     Console c = null;
83                     try {
84                         c = getBackgroundConsole();
85                     } catch (Exception e) {/**NON BLOCK**/}
86                     if (c != null) {
87                         c.reloadTrace();
88                     }
89                     try {
90                         c = ConsoleBuilder.getConsole(context, false);
91                         if (c != null) {
92                             c.reloadTrace();
93                         }
94                     } catch (Throwable _throw) {/**NON BLOCK**/}
95                 }
96             }
97         }
98     };
99
100
101     /**
102      * {@inheritDoc}
103      */
104     @Override
105     public void onCreate() {
106         if (DEBUG) {
107             Log.d(TAG, "FileManagerApplication.onCreate"); //$NON-NLS-1$
108         }
109         register();
110         init();
111     }
112
113     /**
114      * {@inheritDoc}
115      */
116     @Override
117     public void onTerminate() {
118         if (DEBUG) {
119             Log.d(TAG, "onTerminate"); //$NON-NLS-1$
120         }
121         try {
122             unregisterReceiver(this.mOnSettingChangeReceiver);
123         } catch (Throwable ex) {
124             /**NON BLOCK**/
125         }
126         try {
127             destroyBackgroundConsole();
128         } catch (Throwable ex) {
129             /**NON BLOCK**/
130         }
131         try {
132             ConsoleBuilder.destroyConsole();
133         } catch (Throwable ex) {
134             /**NON BLOCK**/
135         }
136         super.onTerminate();
137     }
138
139     /**
140      * Method that register the application context.
141      */
142     private void register() {
143         //Save the static application reference
144         sApp = this;
145
146         // Read the system properties
147         sSystemProperties = new Properties();
148         readSystemProperties();
149
150         // Check if the application is debuggable
151         sIsDebuggable = (0 != (getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE));
152
153         // Check if the device is rooted
154         sIsDeviceRooted =
155                 new File(getString(R.string.su_binary)).exists() &&
156                 getSystemProperty("ro.cm.version") != null; //$NON-NLS-1$
157
158         // Register the broadcast receiver
159         IntentFilter filter = new IntentFilter();
160         filter.addAction(FileManagerSettings.INTENT_SETTING_CHANGED);
161         registerReceiver(this.mOnSettingChangeReceiver, filter);
162     }
163
164     /**
165      * Method that initializes the application.
166      */
167     private void init() {
168         //Sets the default preferences if no value is set yet
169         FileHelper.ROOT_DIRECTORY = getString(R.string.root_dir);
170         Preferences.loadDefaults();
171
172         //Create a console for background tasks
173         allocBackgroundConsole(getApplicationContext());
174
175         //Force the load of mime types
176         try {
177             MimeTypeHelper.loadMimeTypes(getApplicationContext());
178         } catch (Exception e) {
179             Log.e(TAG, "Mime-types failed.", e); //$NON-NLS-1$
180         }
181     }
182
183     /**
184      * Method that returns the singleton reference of the application.
185      *
186      * @return Application The application singleton reference
187      * @hide
188      */
189     public static FileManagerApplication getInstance() {
190         return sApp;
191     }
192
193     /**
194      * Method that returns if the application is debuggable
195      *
196      * @return boolean If the application is debuggable
197      */
198     public static boolean isDebuggable() {
199         return sIsDebuggable;
200     }
201
202     /**
203      * Method that returns if the device is rooted
204      *
205      * @return boolean If the device is rooted
206      */
207     public static boolean isDeviceRooted() {
208         return sIsDeviceRooted;
209     }
210
211     /**
212      * Method that returns a system property value
213      *
214      * @param property The system property key
215      * @return String The system property value
216      */
217     public static String getSystemProperty(String property) {
218         return sSystemProperties.getProperty(property);
219     }
220
221     /**
222      * Method that returns the application background console.
223      *
224      * @return Console The background console
225      */
226     public static Console getBackgroundConsole() {
227         if (!sBackgroundConsole.getConsole().isActive()) {
228             allocBackgroundConsole(getInstance().getApplicationContext());
229         }
230         return sBackgroundConsole.getConsole();
231     }
232
233     /**
234      * Method that destroy the background console
235      */
236     public static void destroyBackgroundConsole() {
237         try {
238             sBackgroundConsole.dispose();
239         } catch (Throwable ex) {
240             /**NON BLOCK**/
241         }
242     }
243
244     /**
245      * Method that allocate a new background console
246      *
247      * @param ctx The current context
248      */
249     private static synchronized void allocBackgroundConsole(Context ctx) {
250         try {
251             // Dispose the current console
252             if (sBackgroundConsole != null) {
253                 sBackgroundConsole.dispose();
254                 sBackgroundConsole = null;
255             }
256
257             //Create a console for background tasks
258             if (ConsoleBuilder.isPrivileged()) {
259                 sBackgroundConsole =
260                         new ConsoleHolder(
261                                 ConsoleBuilder.createPrivilegedConsole(
262                                         ctx, FileHelper.ROOT_DIRECTORY));
263             } else {
264                 sBackgroundConsole =
265                         new ConsoleHolder(
266                                 ConsoleBuilder.createNonPrivilegedConsole(
267                                         ctx, FileHelper.ROOT_DIRECTORY));
268             }
269         } catch (Exception e) {
270             Log.e(TAG,
271                     "Background console creation failed. " +  //$NON-NLS-1$
272                     "This probably will cause a force close.", e); //$NON-NLS-1$
273         }
274     }
275
276     /**
277      * Method that changes the background console to a privileged console
278      *
279      * @throws ConsoleAllocException If the console can't be allocated
280      */
281     public static void changeBackgroundConsoleToPriviligedConsole()
282             throws ConsoleAllocException {
283         if (sBackgroundConsole == null ||
284               !(sBackgroundConsole.getConsole() instanceof PrivilegedConsole)) {
285             try {
286                 if (sBackgroundConsole != null) {
287                     sBackgroundConsole.dispose();
288                 }
289             } catch (Throwable ex) {/**NON BLOCK**/}
290
291             // Change the privileged console
292             try {
293                 sBackgroundConsole =
294                         new ConsoleHolder(
295                                 ConsoleBuilder.createPrivilegedConsole(
296                                         getInstance().getApplicationContext(),
297                                         FileHelper.ROOT_DIRECTORY));
298             } catch (Exception e) {
299                 try {
300                     if (sBackgroundConsole != null) {
301                         sBackgroundConsole.dispose();
302                     }
303                 } catch (Throwable ex) {/**NON BLOCK**/}
304                 sBackgroundConsole = null;
305                 throw new ConsoleAllocException(
306                         "Failed to alloc background console", e); //$NON-NLS-1$
307             }
308         }
309     }
310
311     /**
312      * Method that check if the app is signed with the platform signature
313      *
314      * @param ctx The current context
315      * @return boolean If the app is signed with the platform signature
316      */
317     public static boolean isAppPlatformSignature(Context ctx) {
318         // TODO This need to be improved, checking if the app is really with the platform signature
319         try {
320             // For now only check that the app is installed in system directory
321             PackageManager pm = ctx.getPackageManager();
322             String appDir = pm.getApplicationInfo(ctx.getPackageName(), 0).sourceDir;
323             String systemDir = ctx.getString(R.string.system_dir);
324             return appDir.startsWith(systemDir);
325
326         } catch (Exception e) {
327             ExceptionUtil.translateException(ctx, e, true, false);
328         }
329         return false;
330     }
331
332     /**
333      * Method that returns the access mode of the application
334      *
335      * @return boolean If the access mode of the application
336      */
337     public static AccessMode getAccessMode() {
338         String defaultValue =
339                 ((ObjectStringIdentifier)FileManagerSettings.
340                             SETTINGS_ACCESS_MODE.getDefaultValue()).getId();
341         String id = FileManagerSettings.SETTINGS_ACCESS_MODE.getId();
342         AccessMode mode =
343                 AccessMode.fromId(Preferences.getSharedPreferences().getString(id, defaultValue));
344         return mode;
345     }
346
347     /**
348      * Method that reads the system properties
349      */
350     private static void readSystemProperties() {
351         try {
352             String propsFile =
353                     getInstance().getApplicationContext().getString(R.string.system_props_file);
354             Properties props = new Properties();
355             props.load(new FileInputStream(new File(propsFile)));
356             sSystemProperties = props;
357         } catch (Throwable e) {
358             Log.e(TAG,
359                     "Failed to read system properties.", e); //$NON-NLS-1$
360         }
361     }
362
363 }