// Copyright 2011 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.android.stardroid.util;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.util.Log;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/**
* Tracks changes in preferences and logs them to Google Analytics.
*
* @author John Taylor
*/
public class PreferenceChangeAnalyticsTracker implements OnSharedPreferenceChangeListener {
private Analytics analytics;
private static final String TAG = MiscUtil.getTag(PreferenceChangeAnalyticsTracker.class);
public PreferenceChangeAnalyticsTracker(Analytics analytics) {
this.analytics = analytics;
}
private Set<String> stringPreferenceWhiteList = new HashSet<String>(Arrays.asList(new String[] {
"sensor_speed", "sensor_damping"
}));
private void trackPreferenceChange(SharedPreferences sharedPreferences, String key) {
Log.d(TAG, "Logging pref change " + key);
// There is no way to get a preference without knowing its type. Consequently, we try
// each type and silently swallow the exception if we guess wrong. If this proves expensive
// we might switch to caching the type.
try {
String value = sharedPreferences.getString(key, "unknown");
// Unlike the numeric valued preferences, we could inadvertently log PII if we blindly log
// all String values.
// Instead we maintain a whitelist of things we're allowed to log. If the key isn't in
// the whitelist, then we only log that it changed, not what it changed to.
if (!stringPreferenceWhiteList.contains(key)) {
value = "PII";
}
analytics.trackEvent(Analytics.USER_ACTION_CATEGORY,
"Preference: " + key, "Preference: " + value, 0);
return;
} catch (ClassCastException cce) {
// Thrown if the pref wasn't a string.
}
try {
boolean value = sharedPreferences.getBoolean(key, false);
analytics.trackEvent(Analytics.USER_ACTION_CATEGORY,
Analytics.PREFERENCE_TOGGLE, "Preference:" + key, value ? 1 : 0);
return;
} catch (ClassCastException cce) {
// Thrown if the pref wasn't a boolean.
}
try {
int value = sharedPreferences.getInt(key, 0);
analytics.trackEvent(Analytics.USER_ACTION_CATEGORY,
Analytics.PREFERENCE_TOGGLE, "Preference:" + key, value);
return;
} catch (ClassCastException cce) {
// Thrown if the pref wasn't an integer.
}
try {
@SuppressWarnings("unused")
long unused = sharedPreferences.getLong(key, 0);
analytics.trackEvent(Analytics.USER_ACTION_CATEGORY,
Analytics.PREFERENCE_TOGGLE, "Preference:" + key, 0);
return;
} catch (ClassCastException cce) {
// Thrown if the pref wasn't an integer.
}
try {
@SuppressWarnings("unused")
float unused = sharedPreferences.getFloat(key, 0);
analytics.trackEvent(Analytics.USER_ACTION_CATEGORY,
Analytics.PREFERENCE_TOGGLE, "Preference:" + key, 0);
return;
} catch (ClassCastException cce) {
// Thrown if the pref wasn't a float.
}
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
trackPreferenceChange(sharedPreferences, key);
}
}