HIC: Add report facility for overzealous anti-falsing

am: 7bb38a941b

Change-Id: Ie40c0e42dcdc788757f18f65d8edc3e8ba2a6995
This commit is contained in:
Adrian Roos
2016-08-04 23:37:29 +00:00
committed by android-build-merger
7 changed files with 136 additions and 7 deletions

View File

@@ -65,6 +65,14 @@
layout="@layout/keyguard_status_bar"
android:visibility="invisible" />
<Button
android:id="@+id/report_rejected_touch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/status_bar_header_height_keyguard"
android:text="@string/report_rejected_touch"
android:visibility="gone" />
</com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer>
<include

View File

@@ -1629,6 +1629,9 @@
<!-- Accessibility label for the notification icons in the collapsed status bar. Not shown on screen [CHAR LIMIT=NONE] -->
<string name="accessibility_desc_notification_icon"><xliff:g name="app_name" example="Gmail">%1$s</xliff:g> notification: <xliff:g name="notification_text" example="5 new messages">%2$s</xliff:g></string>
<!-- Label for button that reports a touch that was wrongly rejected by the lockscreen. For debugging only. [CHAR LIMIT=NONE] -->
<string name="report_rejected_touch" translatable="false">Report rejected touch</string>
<!-- Multi-Window strings -->
<!-- Text that gets shown on top of current activity to inform the user that the system force-resized the current activity and that things might crash/not work properly [CHAR LIMIT=NONE] -->
<string name="dock_forced_resizable">App may not work with split-screen.</string>

View File

@@ -21,6 +21,7 @@ import android.database.ContentObserver;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Handler;
@@ -28,6 +29,7 @@ import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
@@ -48,6 +50,8 @@ public class DataCollector implements SensorEventListener {
private static final String TAG = "DataCollector";
private static final String COLLECTOR_ENABLE = "data_collector_enable";
private static final String COLLECT_BAD_TOUCHES = "data_collector_collect_bad_touches";
private static final String ALLOW_REJECTED_TOUCH_REPORTS =
"data_collector_allow_rejected_touch_reports";
private static final long TIMEOUT_MILLIS = 11000; // 11 seconds.
public static final boolean DEBUG = false;
@@ -64,6 +68,7 @@ public class DataCollector implements SensorEventListener {
private boolean mCollectBadTouches = false;
private boolean mCornerSwiping = false;
private boolean mTrackingStarted = false;
private boolean mAllowReportRejectedTouch = false;
private static DataCollector sInstance = null;
@@ -87,6 +92,11 @@ public class DataCollector implements SensorEventListener {
mSettingsObserver,
UserHandle.USER_ALL);
mContext.getContentResolver().registerContentObserver(
Settings.Secure.getUriFor(ALLOW_REJECTED_TOUCH_REPORTS), false,
mSettingsObserver,
UserHandle.USER_ALL);
updateConfiguration();
}
@@ -104,10 +114,13 @@ public class DataCollector implements SensorEventListener {
mCollectBadTouches = mEnableCollector && 0 != Settings.Secure.getInt(
mContext.getContentResolver(),
COLLECT_BAD_TOUCHES, 0);
mAllowReportRejectedTouch = Build.IS_DEBUGGABLE && 0 != Settings.Secure.getInt(
mContext.getContentResolver(),
ALLOW_REJECTED_TOUCH_REPORTS, 0);
}
private boolean sessionEntrypoint() {
if (mEnableCollector && mCurrentSession == null) {
if (isEnabled() && mCurrentSession == null) {
onSessionStart();
return true;
}
@@ -115,7 +128,7 @@ public class DataCollector implements SensorEventListener {
}
private void sessionExitpoint(int result) {
if (mEnableCollector && mCurrentSession != null) {
if (mCurrentSession != null) {
onSessionEnd(result);
}
}
@@ -130,8 +143,36 @@ public class DataCollector implements SensorEventListener {
SensorLoggerSession session = mCurrentSession;
mCurrentSession = null;
session.end(System.currentTimeMillis(), result);
queueSession(session);
if (mEnableCollector) {
session.end(System.currentTimeMillis(), result);
queueSession(session);
}
}
public Uri reportRejectedTouch() {
if (mCurrentSession == null) {
Toast.makeText(mContext, "Generating rejected touch report failed: session timed out.",
Toast.LENGTH_LONG).show();
return null;
}
SensorLoggerSession currentSession = mCurrentSession;
currentSession.setType(Session.REJECTED_TOUCH_REPORT);
currentSession.end(System.currentTimeMillis(), Session.SUCCESS);
Session proto = currentSession.toProto();
byte[] b = Session.toByteArray(proto);
File dir = new File(mContext.getExternalCacheDir(), "rejected_touch_reports");
dir.mkdir();
File touch = new File(dir, "rejected_touch_report_" + System.currentTimeMillis());
try {
new FileOutputStream(touch).write(b);
} catch (IOException e) {
throw new RuntimeException(e);
}
return Uri.fromFile(touch);
}
private void queueSession(final SensorLoggerSession currentSession) {
@@ -164,7 +205,7 @@ public class DataCollector implements SensorEventListener {
@Override
public synchronized void onSensorChanged(SensorEvent event) {
if (mEnableCollector && mCurrentSession != null) {
if (isEnabled() && mCurrentSession != null) {
mCurrentSession.addSensorEvent(event, System.nanoTime());
enforceTimeout();
}
@@ -186,7 +227,19 @@ public class DataCollector implements SensorEventListener {
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
/**
* @return true if data is being collected - either for data gathering or creating a
* rejected touch report.
*/
public boolean isEnabled() {
return mEnableCollector || mAllowReportRejectedTouch;
}
/**
* @return true if the full data set for data gathering should be collected - including
* extensive sensor data, which is is not normally included with rejected touch reports.
*/
public boolean isEnabledFull() {
return mEnableCollector;
}
@@ -401,8 +454,12 @@ public class DataCollector implements SensorEventListener {
}
private void addEvent(int eventType) {
if (mEnableCollector && mCurrentSession != null) {
if (isEnabled() && mCurrentSession != null) {
mCurrentSession.addPhoneEvent(eventType, System.nanoTime());
}
}
public boolean isReportingEnabled() {
return mAllowReportRejectedTouch;
}
}

View File

@@ -53,6 +53,10 @@ public class SensorLoggerSession {
mType = Session.REAL;
}
public void setType(int type) {
mType = type;
}
public void end(long endTimestampMillis, int result) {
mResult = result;
mEndTimestampMillis = endTimestampMillis;

View File

@@ -22,6 +22,7 @@ import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.net.Uri;
import android.os.Handler;
import android.os.PowerManager;
import android.os.UserHandle;
@@ -142,7 +143,7 @@ public class FalsingManager implements SensorEventListener {
if (mHumanInteractionClassifier.isEnabled()) {
registerSensors(CLASSIFIER_SENSORS);
}
if (mDataCollector.isEnabled()) {
if (mDataCollector.isEnabledFull()) {
registerSensors(COLLECTOR_SENSORS);
}
}
@@ -400,4 +401,15 @@ public class FalsingManager implements SensorEventListener {
pw.print("mScreenOn="); pw.println(mScreenOn ? 1 : 0);
pw.println();
}
public Uri reportRejectedTouch() {
if (mDataCollector.isEnabled()) {
return mDataCollector.reportRejectedTouch();
}
return null;
}
public boolean isReportingEnabled() {
return mDataCollector.isReportingEnabled();
}
}

View File

@@ -73,6 +73,7 @@ import android.media.session.MediaController;
import android.media.session.MediaSession;
import android.media.session.MediaSessionManager;
import android.media.session.PlaybackState;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
@@ -85,6 +86,7 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.Trace;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.Vibrator;
@@ -195,6 +197,7 @@ import com.android.systemui.volume.VolumeComponent;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -365,6 +368,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
private View mPendingRemoteInputView;
private View mPendingWorkRemoteInputView;
private View mReportRejectedTouch;
int mMaxAllowedKeyguardNotifications;
boolean mExpandedVisible;
@@ -929,6 +934,36 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mBatteryController);
mKeyguardStatusBar.setBatteryController(mBatteryController);
mReportRejectedTouch = mStatusBarWindow.findViewById(R.id.report_rejected_touch);
if (mReportRejectedTouch != null) {
updateReportRejectedTouchVisibility();
mReportRejectedTouch.setOnClickListener(v -> {
Uri session = mFalsingManager.reportRejectedTouch();
if (session == null) { return; }
StringWriter message = new StringWriter();
message.write("Build info: ");
message.write(SystemProperties.get("ro.build.description"));
message.write("\nSerial number: ");
message.write(SystemProperties.get("ro.serialno"));
message.write("\n");
PrintWriter falsingPw = new PrintWriter(message);
FalsingLog.dump(falsingPw);
falsingPw.flush();
startActivityDismissingKeyguard(Intent.createChooser(new Intent(Intent.ACTION_SEND)
.setType("*/*")
.putExtra(Intent.EXTRA_SUBJECT, "Rejected touch report")
.putExtra(Intent.EXTRA_STREAM, session)
.putExtra(Intent.EXTRA_TEXT, message.toString()),
"Share rejected touch report")
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
true /* onlyProvisioned */, true /* dismissShade */);
});
}
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mBroadcastReceiver.onReceive(mContext,
new Intent(pm.isScreenOn() ? Intent.ACTION_SCREEN_ON : Intent.ACTION_SCREEN_OFF));
@@ -2260,6 +2295,14 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
Trace.endSection();
}
private void updateReportRejectedTouchVisibility() {
if (mReportRejectedTouch == null) {
return;
}
mReportRejectedTouch.setVisibility(mState == StatusBarState.KEYGUARD
&& mFalsingManager.isReportingEnabled() ? View.VISIBLE : View.INVISIBLE);
}
protected int adjustDisableFlags(int state) {
if (!mLaunchTransitionFadingAway && !mKeyguardFadingAway
&& (mExpandedVisible || mBouncerShowing || mWaitingForKeyguardExit)) {
@@ -4394,6 +4437,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mGroupManager.setStatusBarState(state);
mFalsingManager.setStatusBarState(state);
mStatusBarWindowManager.setStatusBarState(state);
updateReportRejectedTouchVisibility();
updateDozing();
}

View File

@@ -120,6 +120,7 @@ message Session {
RESERVED_2 = 1;
RANDOM_WAKEUP = 2;
REAL = 3;
REJECTED_TOUCH_REPORT = 4;
}
optional uint64 startTimestampMillis = 1;