1ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert/*
2ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert * Copyright (C) 2009 The Android Open Source Project
3ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert *
4ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License");
5ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert * you may not use this file except in compliance with the License.
6ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert * You may obtain a copy of the License at
7ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert *
8ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert *      http://www.apache.org/licenses/LICENSE-2.0
9ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert *
10ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert * Unless required by applicable law or agreed to in writing, software
11ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS,
12ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert * See the License for the specific language governing permissions and
14ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert * limitations under the License.
15ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert */
16ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert
17ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringertpackage com.android.quicksearchbox;
18ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert
19ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringertimport android.content.Context;
20ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringertimport android.util.EventLog;
21ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert
22e06b7cbf55301a24cfd7525a91107e3cd2c9f48eBjorn Bringertimport java.util.Collection;
23ce4cdcf739b57563ddcdbed6944128b8c1f7522aBjorn Bringertimport java.util.List;
24f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringertimport java.util.Random;
25ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert
26ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert/**
27ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert * Logs events to {@link EventLog}.
28ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert */
29ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringertpublic class EventLogLogger implements Logger {
30ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert
31ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert    private static final char LIST_SEPARATOR = '|';
32ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert
33ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert    private final Context mContext;
34ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert
35f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert    private final Config mConfig;
36f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert
37f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert    private final String mPackageName;
38f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert
39f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert    private final Random mRandom;
40f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert
41f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert    public EventLogLogger(Context context, Config config) {
42ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert        mContext = context;
43f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert        mConfig = config;
4449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        mPackageName = mContext.getPackageName();
45f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert        mRandom = new Random();
46ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert    }
47ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert
48ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert    protected Context getContext() {
49ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert        return mContext;
50ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert    }
51ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert
52ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert    protected int getVersionCode() {
5349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        return QsbApplication.get(getContext()).getVersionCode();
54ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert    }
55ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert
56f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert    protected Config getConfig() {
57f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert        return mConfig;
58f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert    }
59f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert
6098cbee7f6266509a0805b3fef060f01caaef69e3Mathew Inwood    public void logStart(int onCreateLatency, int latency, String intentSource, Corpus corpus,
61ce4cdcf739b57563ddcdbed6944128b8c1f7522aBjorn Bringert            List<Corpus> orderedCorpora) {
62ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert        // TODO: Add more info to startMethod
63ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert        String startMethod = intentSource;
64fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        String currentCorpus = getCorpusLogName(corpus);
65fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        String enabledCorpora = getCorpusLogNames(orderedCorpora);
6649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        EventLogTags.writeQsbStart(mPackageName, getVersionCode(), startMethod,
6798cbee7f6266509a0805b3fef060f01caaef69e3Mathew Inwood                latency, currentCorpus, enabledCorpora, onCreateLatency);
68ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert    }
69ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert
707a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood    public void logSuggestionClick(long id, SuggestionCursor suggestionCursor,
715f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert            Collection<Corpus> queriedCorpora, int clickType) {
72ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert        String suggestions = getSuggestions(suggestionCursor);
73fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        String corpora = getCorpusLogNames(queriedCorpora);
74ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert        int numChars = suggestionCursor.getUserQuery().length();
757a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood        EventLogTags.writeQsbClick(id, suggestions, corpora, numChars,
765f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert                clickType);
77ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert    }
78ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert
79fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    public void logSearch(Corpus corpus, int startMethod, int numChars) {
80fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        String corpusName = getCorpusLogName(corpus);
81fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        EventLogTags.writeQsbSearch(corpusName, startMethod, numChars);
82ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert    }
83ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert
84fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    public void logVoiceSearch(Corpus corpus) {
85fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        String corpusName = getCorpusLogName(corpus);
86fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        EventLogTags.writeQsbVoiceSearch(corpusName);
87ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert    }
88ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert
89fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    public void logExit(SuggestionCursor suggestionCursor, int numChars) {
90ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert        String suggestions = getSuggestions(suggestionCursor);
91fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        EventLogTags.writeQsbExit(suggestions, numChars);
92ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert    }
93ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert
94f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert    public void logLatency(CorpusResult result) {
95f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert        if (!shouldLogLatency()) return;
96f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert        String corpusName = getCorpusLogName(result.getCorpus());
97f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert        int latency = result.getLatency();
98f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert        int numChars = result.getUserQuery().length();
99f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert        EventLogTags.writeQsbLatency(corpusName, latency, numChars);
100f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert    }
101f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert
102f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert    private boolean shouldLogLatency() {
103f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert        int freq = mConfig.getLatencyLogFrequency();
104f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert        return freq > mRandom.nextInt(1000);
105ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert    }
106ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert
107fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    private String getCorpusLogName(Corpus corpus) {
108fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        if (corpus == null) return null;
109fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        return corpus.getName();
110ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert    }
111ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert
112883c1bf364e38c5b133afb55f8493a14b65f4dd4Bjorn Bringert    private String getSuggestions(SuggestionCursor cursor) {
113ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert        StringBuilder sb = new StringBuilder();
114f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert        final int count = cursor == null ? 0 : cursor.getCount();
115ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert        for (int i = 0; i < count; i++) {
116ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert            if (i > 0) sb.append(LIST_SEPARATOR);
117883c1bf364e38c5b133afb55f8493a14b65f4dd4Bjorn Bringert            cursor.moveTo(i);
118f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert            String source = cursor.getSuggestionSource().getName();
119883c1bf364e38c5b133afb55f8493a14b65f4dd4Bjorn Bringert            String type = cursor.getSuggestionLogType();
120883c1bf364e38c5b133afb55f8493a14b65f4dd4Bjorn Bringert            if (type == null) type = "";
121883c1bf364e38c5b133afb55f8493a14b65f4dd4Bjorn Bringert            String shortcut = cursor.isSuggestionShortcut() ? "shortcut" : "";
122883c1bf364e38c5b133afb55f8493a14b65f4dd4Bjorn Bringert            sb.append(source).append(':').append(type).append(':').append(shortcut);
123ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert        }
124ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert        return sb.toString();
125ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert    }
126ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert
127e06b7cbf55301a24cfd7525a91107e3cd2c9f48eBjorn Bringert    private String getCorpusLogNames(Collection<Corpus> corpora) {
12859ae239743a26ecc4e3d66485a412fd7c88cbcbfBjorn Bringert        if (corpora == null) return "";
129ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert        StringBuilder sb = new StringBuilder();
130e06b7cbf55301a24cfd7525a91107e3cd2c9f48eBjorn Bringert        for (Corpus corpus : corpora) {
131e06b7cbf55301a24cfd7525a91107e3cd2c9f48eBjorn Bringert            if (sb.length() > 0) sb.append(LIST_SEPARATOR);
132e06b7cbf55301a24cfd7525a91107e3cd2c9f48eBjorn Bringert            sb.append(getCorpusLogName(corpus));
133ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert        }
134ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert        return sb.toString();
135ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert    }
136ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert
137ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert}
138