/*
* Copyright (C) 2015 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.android.switchaccess;
import android.content.Context;
import android.text.TextUtils;
import com.android.utils.AccessibilityNodeInfoUtils;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* ProbabilityModelReader is the bridge between the PPMTrie and the HuffmanTreeBuilder. It provides
* the needed probability distribution to the HuffmanTreeBuilder, which in turns is obtained
* through the PPMTrie interface.
*/
public class ProbabilityModelReader {
Map<Integer, Double> mModel;
PPMTrie mPPMTrie;
/* TODO This should be a file descriptor of the training file, but is temporarily 0 */
int probabilityModelResource = 0;
private final Context mContext;
public ProbabilityModelReader(Context context, int userContextOrder) {
mPPMTrie = new PPMTrie(userContextOrder);
mPPMTrie.initializeTrie(context, probabilityModelResource);
mContext = context;
}
/**
* Given a set of SwitchAccessNodeCompats, computes an integer representation for each
* of them.
*
* @param nodeInfoCompats The SwitchAccessNodeCompats whose representation we are
* interested in.
* @return Returns a map that associates each of the SwitchAccessNodeCompats in the set
* {@code nodeInfoCompats} to an int representation.
*/
/* TODO This should probably be in a separate class. Ultimately we want to be able to
* represent any of the SwitchAcccessNodeCompat as an Integer. It will be a more involved
* process than simply getting the content description for the node.
*/
private Map<SwitchAccessNodeCompat, Integer> getNodeRepresentation(
Set<SwitchAccessNodeCompat> nodeInfoCompats) {
Map<SwitchAccessNodeCompat, Integer> nodeRepresentation = new HashMap<>();
for (SwitchAccessNodeCompat compatNode : nodeInfoCompats) {
if (!TextUtils.isEmpty(AccessibilityNodeInfoUtils.getNodeText(compatNode))) {
String nodeContent = AccessibilityNodeInfoUtils.getNodeText(compatNode).toString();
// TODO The assumption that nodeContent is a char!
nodeRepresentation.put(compatNode, (int) nodeContent.charAt(0));
}
/* TODO Currently if the node's content is null, we just don't have a
* representation. This is a very temporary implementation and should change once a
* more robust implementation is developed to represent a
* SwitchAccessNodeCompat. This implementation works for the keyboard though. */
}
return nodeRepresentation;
}
/**
* Given the user context, computes the probability for all the SwitchAccessNodeCompats in
* the set of {@code nodeInfoCompats}.
*
* @param userContext The context represent the actions that the user has taken so far.
* @param nodeInfoCompats The SwitchAccessNodeCompats whose probability value we are
* interested in.
* @return Returns a map that associates each of the SwitchAccessNodeCompats in the set
* {@code nodeInfoCompats} to a probability value.
*/
public Map<SwitchAccessNodeCompat, Double> getProbabilityDistribution(String userContext,
Set<SwitchAccessNodeCompat> nodeInfoCompats) {
Map<SwitchAccessNodeCompat, Integer> nodesRepresentation =
getNodeRepresentation(nodeInfoCompats);
Map<Integer, Double> nodeRepresentationProbabilities =
mPPMTrie.getProbabilityDistribution(userContext,
new HashSet<>(nodesRepresentation.values()));
Map<SwitchAccessNodeCompat, Double> compatNodesProbabilities = new HashMap<>();
for (SwitchAccessNodeCompat compatNode : nodeInfoCompats) {
Integer nodeRepresentation = nodesRepresentation.get(compatNode);
if (nodeRepresentation != null) {
compatNodesProbabilities.put(compatNode,
nodeRepresentationProbabilities.get(nodeRepresentation));
} else {
/* TODO This should not happen once we have a robust way to represent
* each AccessibilityNodeInfoCompat */
Double defaultProbability = 1.0 / nodeInfoCompats.size();
compatNodesProbabilities.put(compatNode, defaultProbability);
}
}
return compatNodesProbabilities;
}
}