Browse Source

Profiles are now being persisted to the filesystem

Alexander Brakowski 10 years ago
parent
commit
42337e868f

+ 15 - 0
res/drawable/panel_warning_bg.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+	<!-- White Top color -->
+	<item android:bottom="4px">
+
+		<shape android:shape="rectangle">
+
+			<solid android:color="@color/holo_red" />
+			<corners android:radius="4dp" />
+
+		</shape>
+
+	</item>
+</selector>

+ 43 - 0
res/layout/preference_warning.xml

@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content"
+              android:gravity="center_vertical">
+
+	<LinearLayout android:layout_width="match_parent"
+	              android:layout_height="wrap_content"
+				  android:layout_marginTop="6dip"
+				  android:layout_marginBottom="6dip"
+				  android:minHeight="?android:attr/listPreferredItemHeight"
+				  android:background="@drawable/panel_warning_bg"
+				  android:paddingEnd="?android:attr/scrollbarSize">
+	<RelativeLayout
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"
+			android:layout_marginStart="15dip"
+			android:layout_marginEnd="6dip"
+			android:layout_marginTop="6dip"
+			android:layout_marginBottom="6dip"
+			android:layout_weight="1">
+
+		<TextView android:id="@+android:id/title"
+		          android:layout_width="wrap_content"
+		          android:layout_height="wrap_content"
+		          android:singleLine="true"
+		          android:textAppearance="?android:attr/textAppearanceLarge"
+		          android:ellipsize="marquee"
+		          android:fadingEdge="horizontal" />
+
+		<TextView android:id="@+android:id/summary"
+		          android:layout_width="wrap_content"
+		          android:layout_height="wrap_content"
+		          android:layout_below="@android:id/title"
+		          android:layout_alignStart="@android:id/title"
+		          android:textAppearance="?android:attr/textAppearanceSmall"
+		          android:textColor="#FFFFFFFF"
+		          android:maxLines="4" />
+
+	</RelativeLayout>
+	</LinearLayout>
+</LinearLayout>

+ 11 - 0
res/values/protocols.xml

@@ -13,4 +13,15 @@
         <item>TELNET</item>
     </string-array>
 
+	<string-array name="protocols_description">
+		<item>A service for testing and measurement of round-trip times in IP networks</item>
+		<item>A protocol used to transfer files from one host to another host</item>
+		<item>A protocol mirrors an incoming connection back to the attacker on the same port, that it is running on</item>
+		<item>A protocol to exchange or transfer hypertext. It is the foundation of data communication for the World Wide Web</item>
+		<item>The same as HTTP, but using a secure connections based on SSL/TLS</item>
+		<item>The world\'s second most widely used relational database management system</item>
+		<item>A protocol used for providing shared access to files, printers, serial ports, and miscellaneous communications between nodes on a network</item>
+		<item>A network protocol that provides file access, file transfer, and file management functionalities over any reliable data stream</item>
+		<item>A network protocol used on the Internet or local area networks to provide a bidirectional interactive text-oriented communication facility using a virtual terminal connection</item>
+	</string-array>
 </resources>

+ 1 - 0
res/values/strings.xml

@@ -96,4 +96,5 @@
     <string name="delete_profile">Delete profile</string>
     <string name="discard">Discard</string>
     <string name="save">Save</string>
+	<string name="really_want_delete_profiel">Do you really want to delete this profile?</string>
 </resources>

+ 10 - 0
res/xml/profile_preferences.xml

@@ -1,6 +1,11 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+	<Preference android:summary="Please note, that this profile can't be edited. If you make any changes to this profile, a new profile will be created."
+				android:layout="@layout/preference_warning"
+				android:key="pref_profile_warning"
+				android:enabled="false" />
+
 	<PreferenceCategory android:title="@string/general"
 	                    android:key="pref_profile_general_settings">
 		<EditTextPreference android:key="pref_profile_general_name"
@@ -17,4 +22,9 @@
 		            android:title="Icon"
 		            android:summary="@string/change_icon_of_profile" />
 	</PreferenceCategory>
+
+	<PreferenceCategory android:title="Montior protocols"
+	                    android:key="pref_profile_protocols_settings">
+		<Preference android:summary="Activate the protocols that should be monitored by HosTaGe" />
+	</PreferenceCategory>
 </PreferenceScreen>

+ 146 - 45
src/de/tudarmstadt/informatik/hostage/dao/ProfileManager.java

@@ -1,5 +1,15 @@
 package de.tudarmstadt.informatik.hostage.dao;
 
+import android.content.Context;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.io.StreamCorruptedException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -7,8 +17,8 @@ import java.util.List;
 import java.util.Map;
 
 import de.tudarmstadt.informatik.hostage.R;
-import de.tudarmstadt.informatik.hostage.logging.UglyDbHelper;
 import de.tudarmstadt.informatik.hostage.model.Profile;
+import de.tudarmstadt.informatik.hostage.model.ProfilesHolder;
 import de.tudarmstadt.informatik.hostage.ui2.activity.MainActivity;
 import de.tudarmstadt.informatik.hostage.ui2.adapter.ProfileManagerListAdapter;
 
@@ -19,44 +29,87 @@ import de.tudarmstadt.informatik.hostage.ui2.adapter.ProfileManagerListAdapter;
 public class ProfileManager {
 	private static ProfileManager INSTANCE = null;
 
-	private Map<Integer, Profile> mProfiles;
 	private ProfileManagerListAdapter mProfileListAdapter = null;
-
-	private int mProfileId = 0;
 	private Profile mCurrentActivatedProfile = null;
+	private Profile mRandomProfile = null;
+
+	private static final String PERSIST_FILENAME = "hostage_profiles.dat";
 
-	private UglyDbHelper dbh;
+	private ProfilesHolder holder;
 
 	public static ProfileManager getInstance(){
 		if(INSTANCE == null){
 			INSTANCE = new ProfileManager();
 		}
 
+		if(INSTANCE.getNumberOfProfiles() == 0){
+			INSTANCE.loadData();
+		}
+
 		return INSTANCE;
 	}
 
 	private ProfileManager(){
-		this.mProfiles = new HashMap<Integer, Profile>();
-		this.dbh = new UglyDbHelper(MainActivity.getContext());
+		holder = new ProfilesHolder();
+		holder.mProfiles = new HashMap<Integer, Profile>();
 	}
 
 	public void loadData(){
-		Collection<Profile> profiles = this.dbh.getAllProfiles();
+		try {
+			FileInputStream fin = MainActivity.getContext().openFileInput(PERSIST_FILENAME);
+			ObjectInputStream ois = new ObjectInputStream(fin);
+
+			Object obj = ois.readObject();
+			ois.close();
+			fin.close();
+
+			if(obj != null && obj instanceof ProfilesHolder){
+				this.holder = (ProfilesHolder) obj;
+
+				for(Map.Entry<Integer, Profile> entry: holder.mProfiles.entrySet()){
+					if(entry.getValue().mActivated){
+						this.mCurrentActivatedProfile = entry.getValue();
+					}
+
+					if(entry.getValue().mIsRandom){
+						this.mRandomProfile = entry.getValue();
+					}
+				}
+			}
+		} catch (FileNotFoundException e) {
+			e.printStackTrace();
+		} catch (StreamCorruptedException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		} catch (ClassNotFoundException e) {
+			e.printStackTrace();
+		} finally {
+			if(holder.mProfiles.size() == 0){
+				this.fillWithSampleData();
+				loadData();
+			}
 
-		if(profiles.size() == 0){
-			this.fillWithSampleData();
-			profiles = this.dbh.getAllProfiles();
+			if(this.mRandomProfile != null){
+				randomizeProtocols(mRandomProfile);
+			}
 		}
+	}
 
-		this.mProfiles.clear();
-
-		for(Profile p: profiles){
-			this.mProfiles.put(p.mId, p);
-
-			if(p.mActivated){
-				this.mCurrentActivatedProfile = p;
-			}
+	public void persistData(){
+		try {
+			FileOutputStream fout = MainActivity.getContext().openFileOutput(PERSIST_FILENAME, Context.MODE_PRIVATE);
+			ObjectOutputStream oos = new ObjectOutputStream(fout);
+
+			oos.writeObject(holder);
+			oos.close();
+			fout.close();
+		} catch (FileNotFoundException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
 		}
+
 	}
 
 	public List<Profile> getProfilesList(){
@@ -64,45 +117,75 @@ public class ProfileManager {
 	}
 
 	public Collection<Profile> getProfilesCollection(){
-		if(mProfiles.size() == 0 || mProfiles == null){
+		if(holder.mProfiles.size() == 0 || holder.mProfiles == null){
 			this.loadData();
 		}
 
-		return mProfiles.values();
+		return holder.mProfiles.values();
 	}
 
 	public Map<Integer, Profile> getMapProfiles(){
-		return mProfiles;
+		return holder.mProfiles;
 	}
 
-	public long persistProfile(Profile profile){
-		int id = (int) this.dbh.persistProfile(profile);
+	public void randomizeProtocols(Profile profile){
+		for(String protocol: MainActivity.getContext().getResources().getStringArray(R.array.protocols)){
+			double rand = Math.random();
+
+			if(rand > 0.4){
+				profile.mActiveProtocols.put(protocol, true);
+			} else {
+				profile.mActiveProtocols.put(protocol, false);
+			}
+		}
+
+		persistData();
+	}
 
-		if(profile.mId != id){
-			profile.mId = id;
+	public long persistProfile(Profile profile){
+		if(profile.mId == -1){
+			profile.mId = ++holder.mIncrementValue;
 		}
 
-		this.mProfiles.put(id, profile);
+		holder.mProfiles.put(profile.mId, profile);
+
+		this.persistData();
 
-		return id;
+		if(this.mProfileListAdapter != null){
+			this.mProfileListAdapter.notifyDataSetChanged();
+		}
+
+		return profile.mId;
 	}
 
 	public Profile getProfile(int id){
-		if(this.mProfiles.containsKey(id)){
-			return this.mProfiles.get(id);
+		if(holder.mProfiles.size() == 0){
+			loadData();
 		}
 
-		Profile profile = this.dbh.getProfile(id);
-		if(profile != null) return profile;
+		if(this.holder.mProfiles.containsKey(id)){
+			return this.holder.mProfiles.get(id);
+		}
 
 		return null;
 	}
 
 	public void addProfile(Profile profile){
-		int id = (int) this.dbh.persistProfile(profile);
-		profile.mId = id;
+		this.addProfile(profile, true);
+	}
+
+	public void addProfile(Profile profile, boolean persist){
+
+		if(profile.mId == -1){
+			profile.mId = ++holder.mIncrementValue;
+		}
+
+		holder.mProfiles.put(profile.mId, profile);
+
+		if(persist){
+			persistData();
+		}
 
-		this.mProfiles.put(id, profile);
 		if(this.mProfileListAdapter != null){
 			this.mProfileListAdapter.add(profile);
 			this.mProfileListAdapter.notifyDataSetChanged();
@@ -110,9 +193,10 @@ public class ProfileManager {
 	}
 
 	public void deleteProfile(Profile profile){
-		if(this.mProfiles.containsKey(profile.mId)){
-			this.mProfiles.remove(profile.mId);
-			this.dbh.deleteProfile(profile.mId);
+		if(this.holder.mProfiles.containsKey(profile.mId)){
+			this.holder.mProfiles.remove(profile.mId);
+			this.persistData();
+			//this.dbh.deleteProfile(profile.mId);
 
 			if(this.mProfileListAdapter != null){
 				this.mProfileListAdapter.remove(profile);
@@ -121,6 +205,11 @@ public class ProfileManager {
 		}
 	}
 
+	public void clearProfiles(){
+		holder.mProfiles.clear();
+		persistData();
+	}
+
 	public void activateProfile(Profile profile){
 		if(profile.equals(this.mCurrentActivatedProfile)) return;
 
@@ -131,7 +220,8 @@ public class ProfileManager {
 
 		profile.mActivated = true;
 		this.mCurrentActivatedProfile = profile;
-		this.dbh.persistProfile(profile);
+		this.holder.mProfiles.put(profile.mId, profile);
+		persistData();
 	}
 
 	public Profile getCurrentActivatedProfile(){
@@ -147,6 +237,10 @@ public class ProfileManager {
 		return this.mProfileListAdapter;
 	}
 
+	public int getNumberOfProfiles(){
+		return holder.mProfiles.size();
+	}
+
 	public void fillWithSampleData(){
 		this.addProfile(new Profile(
 				0,
@@ -154,7 +248,7 @@ public class ProfileManager {
 				"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.",
 				R.drawable.ic_profile_vista,
 				false
-		));
+		), false);
 
 		this.addProfile(new Profile(
 				1,
@@ -162,7 +256,7 @@ public class ProfileManager {
 				"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.",
 				R.drawable.ic_profile_w7,
 				false
-		));
+		), false);
 
 		this.addProfile(new Profile(
 				2,
@@ -170,15 +264,19 @@ public class ProfileManager {
 				"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.",
 				R.drawable.ic_profile_unix,
 				false
-		));
+		), false);
 
-		this.addProfile(new Profile(
+		Profile randomProfile = new Profile(
 				3,
 				"Random",
 				"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.",
 				R.drawable.ic_service_green,
 				false
-		));
+		);
+
+		randomProfile.mIsRandom = true;
+
+		this.addProfile(randomProfile, false);
 
 		this.addProfile(new Profile(
 				4,
@@ -186,6 +284,9 @@ public class ProfileManager {
 				"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.",
 				R.drawable.ic_service_green,
 				false
-		));
+		), false);
+
+		holder.mIncrementValue = 4;
+		persistData();
 	}
 }

+ 15 - 43
src/de/tudarmstadt/informatik/hostage/model/Profile.java

@@ -12,6 +12,8 @@ import android.os.Parcelable;
 
 import java.io.Serializable;
 import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Map;
 
 import de.tudarmstadt.informatik.hostage.ui2.activity.MainActivity;
@@ -26,13 +28,14 @@ public class Profile implements Serializable {
 	public int mId;
 	public boolean mActivated;
 	transient public Bitmap mIcon;
-	public int mIconId;
+	transient public int mIconId;
 	public String mIconName;
 
 	public String mIconPath;
 
 	public boolean mIsBackVisible = false;
 	public boolean mEditable = false;
+	public boolean mIsRandom = false;
 
 	public HashMap<String, Boolean> mActiveProtocols = new HashMap<String, Boolean>();
 
@@ -118,6 +121,17 @@ public class Profile implements Serializable {
 		return mActiveProtocols.get(protocol);
 	}
 
+	public List<String> getActiveProtocols(){
+		List<String> list = new LinkedList<String>();
+		for(Map.Entry<String, Boolean> entry: this.mActiveProtocols.entrySet()){
+			if(entry.getValue()){
+				list.add(entry.getKey());
+			}
+		}
+
+		return list;
+	}
+
 	public Drawable getIconDrawable(){
 		return new BitmapDrawable(MainActivity.context.getResources(), getIconBitmap());
 	}
@@ -129,46 +143,4 @@ public class Profile implements Serializable {
 	public Profile cloneProfile(){
 		return new Profile(mId, mLabel, mText, mIcon, mEditable);
 	}
-
-	/**
-	 * Describe the kinds of special objects contained in this Parcelable's
-	 * marshalled representation.
-	 *
-	 * @return a bitmask indicating the set of special object types marshalled
-	 * by the Parcelable.
-	 */
-	//@Override
-	public int describeContents() {
-		return 0;
-	}
-
-	/**
-	 * Flatten this object in to a Parcel.
-	 *
-	 * @param dest  The Parcel in which the object should be written.
-	 * @param flags Additional flags about how the object should be written.
-	 *              May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
-	 */
-	//@Override
-	public void writeToParcel(Parcel dest, int flags) {
-		dest.writeString(this.mText);
-		dest.writeString(this.mLabel);
-		dest.writeInt(this.mId);
-		dest.writeInt(this.mActivated ? 1 : 0);
-		dest.writeInt(this.mIconId);
-		dest.writeString(this.mIconName);
-		dest.writeString(this.mIconPath);
-		dest.writeInt(this.mEditable ? 1 : 0);
-		dest.writeSerializable(mActiveProtocols);
-	}
-
-	public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
-		public Profile createFromParcel(Parcel in) {
-			return new Profile(in);
-		}
-
-		public Profile[] newArray(int size) {
-			return new Profile[size];
-		}
-	};
 }

+ 13 - 0
src/de/tudarmstadt/informatik/hostage/model/ProfilesHolder.java

@@ -0,0 +1,13 @@
+package de.tudarmstadt.informatik.hostage.model;
+
+import java.io.Serializable;
+import java.util.HashMap;
+
+/**
+ * @author Alexander Brakowski
+ * @created 07.03.14 00:23
+ */
+public class ProfilesHolder implements Serializable {
+	public int mIncrementValue = 1;
+	public HashMap<Integer, Profile> mProfiles;
+}

+ 2 - 2
src/de/tudarmstadt/informatik/hostage/ui2/adapter/ProfileManagerListAdapter.java

@@ -92,8 +92,8 @@ public class ProfileManagerListAdapter extends ArrayAdapter<Profile> {
 			public void onClick(View v) {
 				Intent intent = new Intent(context, ProfileEditActivity.class);
 				intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-				//intent.putExtra("profile_id", item.mId);
-				intent.putExtra("profile", item);
+				intent.putExtra("profile_id", item.mId);
+				//intent.putExtra("profile", item);
 				context.startActivity(intent);
 			}
 		});

+ 43 - 5
src/de/tudarmstadt/informatik/hostage/ui2/fragment/ProfileEditFragment.java

@@ -11,15 +11,21 @@ import android.graphics.BitmapFactory;
 import android.graphics.drawable.BitmapDrawable;
 import android.net.Uri;
 import android.os.Bundle;
+import android.preference.CheckBoxPreference;
 import android.preference.EditTextPreference;
+import android.preference.MultiSelectListPreference;
 import android.preference.Preference;
+import android.preference.PreferenceCategory;
 import android.preference.PreferenceFragment;
 import android.preference.PreferenceManager;
+import android.preference.PreferenceScreen;
 import android.provider.MediaStore;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.LinearLayout;
 
+import java.util.HashMap;
+
 import de.tudarmstadt.informatik.hostage.R;
 import de.tudarmstadt.informatik.hostage.dao.ProfileManager;
 import de.tudarmstadt.informatik.hostage.model.Profile;
@@ -34,6 +40,8 @@ public class ProfileEditFragment extends PreferenceFragment implements
 	private LayoutInflater mInflater;
 	private SharedPreferences.Editor prefs;
 
+	private HashMap<String, Boolean> profileProtocols;
+
 	@Override
 	public void onCreate(Bundle savedInstanceState){
 		getActivity().getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
@@ -71,11 +79,14 @@ public class ProfileEditFragment extends PreferenceFragment implements
 				profile.mLabel = prefs.getString("pref_profile_general_name", profile.mLabel);
 				profile.mIconPath = prefs.getString("pref_profile_general_image", profile.mIconPath);
 				profile.mText = prefs.getString("pref_profile_general_description", profile.mText);
+				profile.mActiveProtocols = new HashMap<String, Boolean>(profileProtocols);
 
 				if(createNew){
 					profile.mId = -1;
 					profile.mIconId = 0;
 					profile.mIconName = "";
+					profile.mIsRandom = false;
+					profile.mIcon = null;
 					pmanager.addProfile(profile);
 				} else {
 					pmanager.persistProfile(profile);
@@ -96,7 +107,7 @@ public class ProfileEditFragment extends PreferenceFragment implements
 		prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()).edit();
 
 		String pname = "",
-			   pimage = "",
+			   pimage = null,
 			   pdesc = "";
 
 		if(profile != null){
@@ -119,6 +130,9 @@ public class ProfileEditFragment extends PreferenceFragment implements
 
 		if(profile != null){
 			pref.setIcon(profile.getIconDrawable());
+			profileProtocols = new HashMap<String, Boolean>(profile.mActiveProtocols);
+		} else {
+			profileProtocols = new HashMap<String, Boolean>();
 		}
 
 		pref.setOnPreferenceClickListener(
@@ -139,21 +153,42 @@ public class ProfileEditFragment extends PreferenceFragment implements
 			findPreference("pref_profile_general_name").setSummary(profile.mLabel);
 			findPreference("pref_profile_general_description").setSummary(profile.mText);
 		}
+
+		if(profile == null || profile.isEditable()){
+			getPreferenceScreen().removePreference(findPreference("pref_profile_warning"));
+		}
+
+		PreferenceCategory protocolsCategory = (PreferenceCategory) findPreference("pref_profile_protocols_settings");
+		String[] protocols = getResources().getStringArray(R.array.protocols);
+		String[] protocols_summary = getResources().getStringArray(R.array.protocols_description);
+
+		for(int i = 0; i<protocols.length; i++){
+			prefs.putBoolean("pref_profile_protocol_" + protocols[i], profile != null && profile.isProtocolActive(protocols[i]));
+			prefs.commit();
+
+			CheckBoxPreference check = new CheckBoxPreference(getActivity());
+			check.setTitle(protocols[i]);
+			check.setKey("pref_profile_protocol_" + protocols[i]);
+			check.setSummary(protocols_summary[i]);
+			//check.setChecked(profile != null && profile.isProtocolActive(protocols[i]));
+			//System.out.println("-----------------_> " + profile.isProtocolActive(protocols[i]) + " :: " + protocols[i]);
+			protocolsCategory.addPreference(check);
+		}
 	}
 
 	public Profile getProfile(){
 		ProfileManager pmanager = ProfileManager.getInstance();
 
 		Intent intent = getActivity().getIntent();
-		Profile profile = (Profile) intent.getSerializableExtra("profile");
+		//Profile profile = (Profile) intent.getSerializableExtra("profile");
 
-		/*int profile_id = intent.getIntExtra("profile_id", -1);
+		int profile_id = intent.getIntExtra("profile_id", -1);
 
 		if(profile_id != -1){
 			return pmanager.getProfile(profile_id);
-		}*/
+		}
 
-		return profile;
+		return null;
 	}
 
 	@Override
@@ -184,6 +219,9 @@ public class ProfileEditFragment extends PreferenceFragment implements
 
 		if(p instanceof EditTextPreference){
 			p.setSummary(sharedPreferences.getString(key, ""));
+		} else if(p instanceof CheckBoxPreference){
+			profileProtocols.put(p.getTitle().toString(), ((CheckBoxPreference) p).isChecked());
+			//System.out.println("------------------------------- P: " + ((CheckBoxPreference) p).isChecked());
 		}
 	}