10c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal/*
20c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal * Copyright (C) 2016 The Android Open Source Project
30c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal *
40c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal * Licensed under the Apache License, Version 2.0 (the "License");
50c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal * you may not use this file except in compliance with the License.
60c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal * You may obtain a copy of the License at
70c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal *
80c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal *      http://www.apache.org/licenses/LICENSE-2.0
90c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal *
100c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal * Unless required by applicable law or agreed to in writing, software
110c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal * distributed under the License is distributed on an "AS IS" BASIS,
120c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal * See the License for the specific language governing permissions and
140c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal * limitations under the License.
150c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal */
160c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal
170c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawalpackage com.android.server.wifi;
180c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal
190c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawalimport android.util.Log;
200c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal
210c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawalimport com.android.internal.annotations.Immutable;
220c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal
23e4c87d4f40bbbcd0ba1d0d8d17953763b2ad320emukesh agrawalimport javax.annotation.concurrent.ThreadSafe;
24e4c87d4f40bbbcd0ba1d0d8d17953763b2ad320emukesh agrawal
25573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal/**
26573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal * Provides a WifiLog implementation which uses logd as the
27573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal * logging backend.
28573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal *
29573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal * This class is trivially thread-safe, as instances are immutable.
30573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal * Note, however, that LogMessage instances are _not_ thread-safe.
31573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal */
32e4c87d4f40bbbcd0ba1d0d8d17953763b2ad320emukesh agrawal@ThreadSafe
330c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal@Immutable
340c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawalclass LogcatLog implements WifiLog {
350c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal    private final String mTag;
36e33b3346b262507ef2361d50a89d16bef69d9a57Sohani Rao    private static volatile boolean sVerboseLogging = false;
370c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal
380c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal    LogcatLog(String tag) {
390c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal        mTag = tag;
400c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal    }
410c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal
42e33b3346b262507ef2361d50a89d16bef69d9a57Sohani Rao    public static void enableVerboseLogging(int verboseMode) {
43e33b3346b262507ef2361d50a89d16bef69d9a57Sohani Rao        if (verboseMode > 0) {
44e33b3346b262507ef2361d50a89d16bef69d9a57Sohani Rao            sVerboseLogging = true;
45e33b3346b262507ef2361d50a89d16bef69d9a57Sohani Rao        } else {
46e33b3346b262507ef2361d50a89d16bef69d9a57Sohani Rao            sVerboseLogging = false;
47e33b3346b262507ef2361d50a89d16bef69d9a57Sohani Rao        }
48e33b3346b262507ef2361d50a89d16bef69d9a57Sohani Rao    }
49e33b3346b262507ef2361d50a89d16bef69d9a57Sohani Rao
50573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal    /* New-style methods */
51573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal    @Override
52573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal    public LogMessage err(String format) {
53573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        return makeLogMessage(Log.ERROR, format);
54573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal    }
55573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal
56573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal    @Override
57573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal    public LogMessage warn(String format) {
58573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        return makeLogMessage(Log.WARN, format);
59573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal    }
60573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal
61573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal    @Override
62573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal    public LogMessage info(String format) {
63573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        return makeLogMessage(Log.INFO, format);
64573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal    }
65573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal
66573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal    @Override
67573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal    public LogMessage trace(String format) {
68573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        return makeLogMessage(Log.DEBUG, format);
69573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal    }
70573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal
71573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal    @Override
72573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal    public LogMessage dump(String format) {
73573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        return makeLogMessage(Log.VERBOSE, format);
74573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal    }
75573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal
76f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal    @Override
77f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal    public void eC(String msg) {
78f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal        Log.e(mTag, msg);
79f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal    }
80f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal
81f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal    @Override
82f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal    public void wC(String msg) {
83f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal        Log.w(mTag, msg);
84f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal    }
85f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal
86f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal    @Override
87f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal    public void iC(String msg) {
88f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal        Log.i(mTag, msg);
89f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal    }
90f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal
91f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal    @Override
92f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal    public void tC(String msg) {
93f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal        Log.d(mTag, msg);
94f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal    }
95f5d90be206db98bbd5894afc8d757dd32360b2d9mukesh agrawal
96573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal    /* Legacy methods */
97573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal    @Override
980c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal    public void e(String msg) {
990c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal        Log.e(mTag, msg);
1000c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal    }
1010c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal
102573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal    @Override
1030c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal    public void w(String msg) {
1040c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal        Log.w(mTag, msg);
1050c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal    }
1060c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal
107573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal    @Override
1080c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal    public void i(String msg) {
1090c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal        Log.i(mTag, msg);
1100c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal    }
1110c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal
112573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal    @Override
1130c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal    public void d(String msg) {
1140c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal        Log.d(mTag, msg);
1150c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal    }
1160c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal
117573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal    @Override
1180c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal    public void v(String msg) {
1190c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal        Log.v(mTag, msg);
1200c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal    }
121573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal
122573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal    /* Internal details */
123573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal    private static class RealLogMessage implements WifiLog.LogMessage {
124573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        private final int mLogLevel;
125573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        private final String mTag;
126573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        private final String mFormat;
127573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        private final StringBuilder mStringBuilder;
128573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        private int mNextFormatCharPos;
129573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal
130573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        RealLogMessage(int logLevel, String tag, String format) {
131573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            mLogLevel = logLevel;
132573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            mTag = tag;
133573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            mFormat = format;
134573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            mStringBuilder = new StringBuilder();
135573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            mNextFormatCharPos = 0;
136573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        }
137573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal
138573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        @Override
139573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        public WifiLog.LogMessage r(String value) {
140573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            // Since the logcat back-end is just transitional, we don't attempt to tag sensitive
141573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            // information in it.
142573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            return c(value);
143573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        }
144573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal
145573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        @Override
146573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        public WifiLog.LogMessage c(String value) {
147573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            copyUntilPlaceholder();
148573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            if (mNextFormatCharPos < mFormat.length()) {
149573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal                mStringBuilder.append(value);
150573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal                ++mNextFormatCharPos;
151573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            }
152573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            return this;
153573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        }
154573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal
155573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        @Override
156573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        public WifiLog.LogMessage c(long value) {
157573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            copyUntilPlaceholder();
158573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            if (mNextFormatCharPos < mFormat.length()) {
159573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal                mStringBuilder.append(value);
160573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal                ++mNextFormatCharPos;
161573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            }
162573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            return this;
163573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        }
164573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal
165573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        @Override
166573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        public WifiLog.LogMessage c(char value) {
167573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            copyUntilPlaceholder();
168573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            if (mNextFormatCharPos < mFormat.length()) {
169573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal                mStringBuilder.append(value);
170573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal                ++mNextFormatCharPos;
171573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            }
172573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            return this;
173573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        }
174573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal
175573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        @Override
17664acb4210ced1920fc29caa98a353b2968fd33b5Sohani Rao        public WifiLog.LogMessage c(boolean value) {
17764acb4210ced1920fc29caa98a353b2968fd33b5Sohani Rao            copyUntilPlaceholder();
17864acb4210ced1920fc29caa98a353b2968fd33b5Sohani Rao            if (mNextFormatCharPos < mFormat.length()) {
17964acb4210ced1920fc29caa98a353b2968fd33b5Sohani Rao                mStringBuilder.append(value);
18064acb4210ced1920fc29caa98a353b2968fd33b5Sohani Rao                ++mNextFormatCharPos;
18164acb4210ced1920fc29caa98a353b2968fd33b5Sohani Rao            }
18264acb4210ced1920fc29caa98a353b2968fd33b5Sohani Rao            return this;
18364acb4210ced1920fc29caa98a353b2968fd33b5Sohani Rao        }
18464acb4210ced1920fc29caa98a353b2968fd33b5Sohani Rao
18564acb4210ced1920fc29caa98a353b2968fd33b5Sohani Rao        @Override
186573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        public void flush() {
187573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            if (mNextFormatCharPos < mFormat.length()) {
188573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal                mStringBuilder.append(mFormat, mNextFormatCharPos, mFormat.length());
189573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            }
190e33b3346b262507ef2361d50a89d16bef69d9a57Sohani Rao            if (sVerboseLogging || mLogLevel > Log.DEBUG) {
191e33b3346b262507ef2361d50a89d16bef69d9a57Sohani Rao                Log.println(mLogLevel, mTag, mStringBuilder.toString());
192e33b3346b262507ef2361d50a89d16bef69d9a57Sohani Rao            }
193573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        }
194573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal
195573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        /* Should generally not be used; implemented primarily to aid in testing. */
196573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        public String toString() {
197573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            return mStringBuilder.toString();
198573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        }
199573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal
200573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        private void copyUntilPlaceholder() {
201573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            if (mNextFormatCharPos >= mFormat.length()) {
202573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal                return;
203573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            }
204573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal
205573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            int placeholderPos = mFormat.indexOf(WifiLog.PLACEHOLDER, mNextFormatCharPos);
206573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            if (placeholderPos == -1) {
207573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal                placeholderPos = mFormat.length();
208573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            }
209573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal
210573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            mStringBuilder.append(mFormat, mNextFormatCharPos, placeholderPos);
211573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal            mNextFormatCharPos = placeholderPos;
212573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        }
213573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal    }
214573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal
215573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal    private LogMessage makeLogMessage(int logLevel, String format) {
216573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        // TODO(b/30737821): Consider adding an isLoggable() check.
217573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal        return new RealLogMessage(logLevel, mTag, format);
218573de1504ea684a2a647613659d4771c2a315eeamukesh agrawal    }
2190c96e05ef24dc72fa31b6915ed40f09dc7238276mukesh agrawal}
220