2 * Copyright (C) 2012 The CyanogenMod Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.cyanogenmod.filemanager;
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;
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;
42 import java.io.FileInputStream;
43 import java.util.Properties;
46 * A class that wraps the information of the application (constants,
47 * identifiers, statics variables, ...).
50 public final class FileManagerApplication extends Application {
52 private static final String TAG = "FileManagerApplication"; //$NON-NLS-1$
54 private static boolean DEBUG = false;
55 private static Properties sSystemProperties;
58 * A constant that contains the main process name.
61 public static final String MAIN_PROCESS = "com.cyanogenmod.filemanager"; //$NON-NLS-1$
64 private static FileManagerApplication sApp;
65 private static ConsoleHolder sBackgroundConsole;
67 private static boolean sIsDebuggable = false;
68 private static boolean sIsDeviceRooted = false;
70 private final BroadcastReceiver mOnSettingChangeReceiver = new BroadcastReceiver() {
72 public void onReceive(Context context, Intent intent) {
74 intent.getAction().compareTo(FileManagerSettings.INTENT_SETTING_CHANGED) == 0) {
76 // The settings has changed
77 String key = intent.getStringExtra(FileManagerSettings.EXTRA_SETTING_CHANGED_KEY);
79 key.compareTo(FileManagerSettings.SETTINGS_SHOW_TRACES.getId()) == 0) {
81 // The debug traces setting has changed. Notify to consoles
84 c = getBackgroundConsole();
85 } catch (Exception e) {/**NON BLOCK**/}
90 c = ConsoleBuilder.getConsole(context, false);
94 } catch (Throwable _throw) {/**NON BLOCK**/}
105 public void onCreate() {
107 Log.d(TAG, "FileManagerApplication.onCreate"); //$NON-NLS-1$
117 public void onTerminate() {
119 Log.d(TAG, "onTerminate"); //$NON-NLS-1$
122 unregisterReceiver(this.mOnSettingChangeReceiver);
123 } catch (Throwable ex) {
127 destroyBackgroundConsole();
128 } catch (Throwable ex) {
132 ConsoleBuilder.destroyConsole();
133 } catch (Throwable ex) {
140 * Method that register the application context.
142 private void register() {
143 //Save the static application reference
146 // Read the system properties
147 sSystemProperties = new Properties();
148 readSystemProperties();
150 // Check if the application is debuggable
151 sIsDebuggable = (0 != (getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE));
153 // Check if the device is rooted
155 new File(getString(R.string.su_binary)).exists() &&
156 getSystemProperty("ro.cm.version") != null; //$NON-NLS-1$
158 // Register the broadcast receiver
159 IntentFilter filter = new IntentFilter();
160 filter.addAction(FileManagerSettings.INTENT_SETTING_CHANGED);
161 registerReceiver(this.mOnSettingChangeReceiver, filter);
165 * Method that initializes the application.
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();
172 //Create a console for background tasks
173 allocBackgroundConsole(getApplicationContext());
175 //Force the load of mime types
177 MimeTypeHelper.loadMimeTypes(getApplicationContext());
178 } catch (Exception e) {
179 Log.e(TAG, "Mime-types failed.", e); //$NON-NLS-1$
184 * Method that returns the singleton reference of the application.
186 * @return Application The application singleton reference
189 public static FileManagerApplication getInstance() {
194 * Method that returns if the application is debuggable
196 * @return boolean If the application is debuggable
198 public static boolean isDebuggable() {
199 return sIsDebuggable;
203 * Method that returns if the device is rooted
205 * @return boolean If the device is rooted
207 public static boolean isDeviceRooted() {
208 return sIsDeviceRooted;
212 * Method that returns a system property value
214 * @param property The system property key
215 * @return String The system property value
217 public static String getSystemProperty(String property) {
218 return sSystemProperties.getProperty(property);
222 * Method that returns the application background console.
224 * @return Console The background console
226 public static Console getBackgroundConsole() {
227 if (!sBackgroundConsole.getConsole().isActive()) {
228 allocBackgroundConsole(getInstance().getApplicationContext());
230 return sBackgroundConsole.getConsole();
234 * Method that destroy the background console
236 public static void destroyBackgroundConsole() {
238 sBackgroundConsole.dispose();
239 } catch (Throwable ex) {
245 * Method that allocate a new background console
247 * @param ctx The current context
249 private static synchronized void allocBackgroundConsole(Context ctx) {
251 // Dispose the current console
252 if (sBackgroundConsole != null) {
253 sBackgroundConsole.dispose();
254 sBackgroundConsole = null;
257 //Create a console for background tasks
258 if (ConsoleBuilder.isPrivileged()) {
261 ConsoleBuilder.createPrivilegedConsole(
262 ctx, FileHelper.ROOT_DIRECTORY));
266 ConsoleBuilder.createNonPrivilegedConsole(
267 ctx, FileHelper.ROOT_DIRECTORY));
269 } catch (Exception e) {
271 "Background console creation failed. " + //$NON-NLS-1$
272 "This probably will cause a force close.", e); //$NON-NLS-1$
277 * Method that changes the background console to a privileged console
279 * @throws ConsoleAllocException If the console can't be allocated
281 public static void changeBackgroundConsoleToPriviligedConsole()
282 throws ConsoleAllocException {
283 if (sBackgroundConsole == null ||
284 !(sBackgroundConsole.getConsole() instanceof PrivilegedConsole)) {
286 if (sBackgroundConsole != null) {
287 sBackgroundConsole.dispose();
289 } catch (Throwable ex) {/**NON BLOCK**/}
291 // Change the privileged console
295 ConsoleBuilder.createPrivilegedConsole(
296 getInstance().getApplicationContext(),
297 FileHelper.ROOT_DIRECTORY));
298 } catch (Exception e) {
300 if (sBackgroundConsole != null) {
301 sBackgroundConsole.dispose();
303 } catch (Throwable ex) {/**NON BLOCK**/}
304 sBackgroundConsole = null;
305 throw new ConsoleAllocException(
306 "Failed to alloc background console", e); //$NON-NLS-1$
312 * Method that check if the app is signed with the platform signature
314 * @param ctx The current context
315 * @return boolean If the app is signed with the platform signature
317 public static boolean isAppPlatformSignature(Context ctx) {
318 // TODO This need to be improved, checking if the app is really with the platform signature
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);
326 } catch (Exception e) {
327 ExceptionUtil.translateException(ctx, e, true, false);
333 * Method that returns the access mode of the application
335 * @return boolean If the access mode of the application
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();
343 AccessMode.fromId(Preferences.getSharedPreferences().getString(id, defaultValue));
348 * Method that reads the system properties
350 private static void readSystemProperties() {
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) {
359 "Failed to read system properties.", e); //$NON-NLS-1$