1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you my 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 17package android.bordeaux.services; 18 19import android.os.IBinder; 20import android.util.Log; 21import java.util.HashMap; 22import java.util.ArrayList; 23import java.util.List; 24import java.util.Map; 25import java.util.HashSet; 26import java.util.Iterator; 27import java.io.Serializable; 28import java.io.*; 29import java.lang.Boolean; 30import android.bordeaux.services.FeatureAssembly; 31import android.bordeaux.learning.HistogramPredictor; 32 33/** 34 * This is interface to implement Prediction based on histogram that 35 * uses predictor_histogram from learnerning section 36 */ 37public class Predictor extends IPredictor.Stub 38 implements IBordeauxLearner { 39 private final String TAG = "Predictor"; 40 private ModelChangeCallback modelChangeCallback = null; 41 42 private FeatureAssembly mFeatureAssembly = new FeatureAssembly(); 43 44 public static final String SET_FEATURE = "SetFeature"; 45 public static final String SET_PAIRED_FEATURES = "SetPairedFeatures"; 46 public static final String FEATURE_SEPARATOR = ":"; 47 public static final String USE_HISTORY = "UseHistory"; 48 public static final String PREVIOUS_SAMPLE = "PreviousSample"; 49 50 private boolean mUseHistory = false; 51 private long mHistorySpan = 0; 52 private String mPrevSample; 53 private long mPrevSampleTime; 54 55 // TODO: blacklist should be set outside Bordeaux service! 56 private static final String[] APP_BLACKLIST = { 57 "com.android.contacts", 58 "com.android.chrome", 59 "com.android.providers.downloads.ui", 60 "com.android.settings", 61 "com.android.vending", 62 "com.android.mms", 63 "com.google.android.gm", 64 "com.google.android.gallery3d", 65 "com.google.android.apps.googlevoice", 66 }; 67 68 private HistogramPredictor mPredictor = new HistogramPredictor(APP_BLACKLIST); 69 70 71 /** 72 * Reset the Predictor 73 */ 74 public void resetPredictor(){ 75 mPredictor.resetPredictor(); 76 77 if (modelChangeCallback != null) { 78 modelChangeCallback.modelChanged(this); 79 } 80 } 81 82 /** 83 * Input is a sampleName e.g.action name. This input is then augmented with requested build-in 84 * features such as time and location to create sampleFeatures. The sampleFeatures is then 85 * pushed to the histogram 86 */ 87 public void pushNewSample(String sampleName) { 88 Map<String, String> sampleFeatures = getSampleFeatures(); 89 Log.i(TAG, "pushNewSample " + sampleName + ": " + sampleFeatures); 90 91 // TODO: move to the end of the function? 92 mPrevSample = sampleName; 93 mPrevSampleTime = System.currentTimeMillis(); 94 95 mPredictor.addSample(sampleName, sampleFeatures); 96 if (modelChangeCallback != null) { 97 modelChangeCallback.modelChanged(this); 98 } 99 } 100 101 private Map<String, String> getSampleFeatures() { 102 Map<String, String> sampleFeatures = mFeatureAssembly.getFeatureMap(); 103 long currTime = System.currentTimeMillis(); 104 105 if (mUseHistory && mPrevSample != null && 106 ((currTime - mPrevSampleTime) < mHistorySpan)) { 107 sampleFeatures.put(PREVIOUS_SAMPLE, mPrevSample); 108 } 109 110 return sampleFeatures; 111 } 112 113 // TODO: getTopK samples instead get scord for debugging only 114 /** 115 * return probabilty of an exmple using the histogram 116 */ 117 public List<StringFloat> getTopCandidates(int topK) { 118 Map<String, String> features = getSampleFeatures(); 119 List<Map.Entry<String, Double> > topApps = mPredictor.findTopClasses(features, topK); 120 121 int listSize = topApps.size(); 122 ArrayList<StringFloat> result = new ArrayList<StringFloat>(listSize); 123 for (int i = 0; i < listSize; ++i) { 124 Map.Entry<String, Double> entry = topApps.get(i); 125 result.add(new StringFloat(entry.getKey(), entry.getValue().floatValue())); 126 } 127 return result; 128 } 129 130 /** 131 * Set parameters for 1) using History in probability estimations e.g. consider the last event 132 * and 2) featureAssembly e.g. time and location. 133 */ 134 public boolean setPredictorParameter(String key, String value) { 135 Log.i(TAG, "setParameter : " + key + ", " + value); 136 boolean result = true; 137 if (key.equals(SET_FEATURE)) { 138 result = mFeatureAssembly.registerFeature(value); 139 if (!result) { 140 Log.e(TAG,"Setting on feauture: " + value + " which is not available"); 141 } 142 } else if (key.equals(SET_PAIRED_FEATURES)) { 143 String[] features = value.split(FEATURE_SEPARATOR); 144 result = mFeatureAssembly.registerFeaturePair(features); 145 if (!result) { 146 Log.e(TAG,"Setting feauture pair: " + value + " is not valid"); 147 } 148 } else if (key.equals(USE_HISTORY)) { 149 mUseHistory = true; 150 mHistorySpan = Long.valueOf(value); 151 } else { 152 Log.e(TAG,"Setting parameter " + key + " with " + value + " is not valid"); 153 } 154 return result; 155 } 156 157 // Beginning of the IBordeauxLearner Interface implementation 158 public byte [] getModel() { 159 return mPredictor.getModel(); 160 } 161 162 public boolean setModel(final byte [] modelData) { 163 return mPredictor.setModel(modelData); 164 } 165 166 public IBinder getBinder() { 167 return this; 168 } 169 170 public void setModelChangeCallback(ModelChangeCallback callback) { 171 modelChangeCallback = callback; 172 } 173 // End of IBordeauxLearner Interface implemenation 174} 175