Merge "Call userActivity when dismissing keyguard" into nyc-mr1-dev
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 83e2678..0ba937a 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -171,4 +171,12 @@
*/
public abstract int startActivitiesAsPackage(String packageName,
int userId, Intent[] intents, Bundle bOptions);
+
+ /**
+ * Get the procstate for the UID. The return value will be between
+ * {@link ActivityManager#MIN_PROCESS_STATE} and {@link ActivityManager#MAX_PROCESS_STATE}.
+ * Note if the UID doesn't exist, it'll return {@link ActivityManager#PROCESS_STATE_NONEXISTENT}
+ * (-1).
+ */
+ public abstract int getUidProcessState(int uid);
}
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 18b72e2..ff514bd 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -312,8 +312,8 @@
try {
service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
copy, idOut, user.getIdentifier());
- if (id != idOut[0]) {
- Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
+ if (localLOGV && id != idOut[0]) {
+ Log.v(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index ce2fa81..a42da85 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -242,21 +242,23 @@
}
private void releaseSurfaceTexture() {
- boolean shouldRelease = true;
+ if (mSurface != null) {
+ boolean shouldRelease = true;
- if (mListener != null) {
- shouldRelease = mListener.onSurfaceTextureDestroyed(mSurface);
- }
+ if (mListener != null) {
+ shouldRelease = mListener.onSurfaceTextureDestroyed(mSurface);
+ }
- synchronized (mNativeWindowLock) {
- nDestroyNativeWindow();
- }
+ synchronized (mNativeWindowLock) {
+ nDestroyNativeWindow();
+ }
- if (shouldRelease) {
- mSurface.release();
+ if (shouldRelease) {
+ mSurface.release();
+ }
+ mSurface = null;
+ mHadSurface = true;
}
- mSurface = null;
- mHadSurface = true;
}
/**
diff --git a/docs/html/guide/topics/ui/layout/grid.jd b/docs/html/guide/topics/ui/layout/grid.jd
index 31f9b9c..cc53651 100644
--- a/docs/html/guide/topics/ui/layout/grid.jd
+++ b/docs/html/guide/topics/ui/layout/grid.jd
@@ -23,17 +23,32 @@
<img src="{@docRoot}images/ui/gridlayout.png" alt="" />
-<p>{@link android.widget.TableLayout} positions its children into rows
- and columns. TableLayout containers do not display border lines for their rows, columns,
- or cells. The table will have as many columns as the row with the most cells. A table can leave
-cells empty, but cells cannot span columns, as they can in HTML.</p>
-<p>{@link android.widget.TableRow} objects are the child views of a TableLayout
-(each TableRow defines a single row in the table).
-Each row has zero or more cells, each of which is defined by any kind of other View. So, the cells of a row may be
-composed of a variety of View objects, like ImageView or TextView objects.
-A cell may also be a ViewGroup object (for example, you can nest another TableLayout as a cell).</p>
-<p>The following sample layout has two rows and two cells in each. The accompanying screenshot shows the
-result, with cell borders displayed as dotted lines (added for visual effect). </p>
+<p>
+ {@link android.widget.TableLayout} positions its children into rows and
+ columns. TableLayout containers do not display border lines for their rows,
+ columns, or cells. The table will have as many columns as the row with the
+ most cells. A table can leave cells empty. Cells can span multiple columns,
+ as they can in HTML. You can span columns by using the <code>span</code>
+ field in the {@link android.widget.TableRow.LayoutParams} class.
+</p>
+
+<p class="note">
+ <strong>Note:</strong> Cells cannot span multiple rows.
+</p>
+
+<p>
+ {@link android.widget.TableRow} objects are the child views of a TableLayout
+ (each TableRow defines a single row in the table). Each row has zero or more
+ cells, each of which is defined by any kind of other View. So, the cells of
+ a row may be composed of a variety of View objects, like ImageView or
+ TextView objects. A cell may also be a ViewGroup object (for example, you
+ can nest another TableLayout as a cell).
+</p>
+<p>
+ The following sample layout has two rows and two cells in each. The
+ accompanying screenshot shows the result, with cell borders displayed as
+ dotted lines (added for visual effect).
+</p>
<table class="columns">
<tr>
diff --git a/docs/html/wear/preview/api-overview.jd b/docs/html/wear/preview/api-overview.jd
index 4233624..0b3ac6b 100644
--- a/docs/html/wear/preview/api-overview.jd
+++ b/docs/html/wear/preview/api-overview.jd
@@ -45,19 +45,19 @@
<p>
The Android Wear Preview API is still in active development, but you can try
it now as part of the Wear 2.0 Developer Preview. The sections below
- highlight some of the new features for Wear developers.
+ highlight some of the new features for Android Wear developers.
</p>
<h2 id="ui">User Interface Improvements</h2>
-<p>The preview introduces powerful additions to the user interface, opening up
-exciting possibilities to developers.
-A complication is any feature in a watch face that displays more than hours and
-minutes. With the Complications API,
- watch faces can display extra information and separate apps can expose complication
- data.
-The navigation and action drawers provide users with new ways to interact with apps.
+<p>
+ The preview introduces powerful additions to the user interface, opening up
+ exciting possibilities to developers. A complication
+ is any feature in a watch face that displays more than hours and
+ minutes. With the Complications API, watch faces can display extra information
+ and separate apps can expose complication data. The navigation and action
+ drawers provide users with new ways to interact with apps.
</p>
@@ -69,8 +69,8 @@
A <a href=
"https://en.wikipedia.org/wiki/Complication_(horology)">complication</a> is a
feature of a watch face that displays more than hours and minutes, such as a
- battery indicator or a step counter. The Complications API helps watch face
- developers create these features visual features and data connections they
+ battery indicator or a step counter. The Complications API thus helps watch face
+ developers create visual features and the data connections they
require.
</p>
diff --git a/packages/Shell/src/com/android/shell/Screenshooter.java b/packages/Shell/src/com/android/shell/Screenshooter.java
index 3f4895b..ce0fbbc 100644
--- a/packages/Shell/src/com/android/shell/Screenshooter.java
+++ b/packages/Shell/src/com/android/shell/Screenshooter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 2c8a559..3d70969 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -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
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 935894c..6c48b25 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -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>
diff --git a/packages/SystemUI/src/com/android/systemui/analytics/DataCollector.java b/packages/SystemUI/src/com/android/systemui/analytics/DataCollector.java
index 91f6520..b1f454e 100644
--- a/packages/SystemUI/src/com/android/systemui/analytics/DataCollector.java
+++ b/packages/SystemUI/src/com/android/systemui/analytics/DataCollector.java
@@ -21,6 +21,7 @@
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.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 @@
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 @@
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 @@
mSettingsObserver,
UserHandle.USER_ALL);
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(ALLOW_REJECTED_TOUCH_REPORTS), false,
+ mSettingsObserver,
+ UserHandle.USER_ALL);
+
updateConfiguration();
}
@@ -104,10 +114,13 @@
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 @@
}
private void sessionExitpoint(int result) {
- if (mEnableCollector && mCurrentSession != null) {
+ if (mCurrentSession != null) {
onSessionEnd(result);
}
}
@@ -130,8 +143,36 @@
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 @@
@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 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 @@
}
private void addEvent(int eventType) {
- if (mEnableCollector && mCurrentSession != null) {
+ if (isEnabled() && mCurrentSession != null) {
mCurrentSession.addPhoneEvent(eventType, System.nanoTime());
}
}
+
+ public boolean isReportingEnabled() {
+ return mAllowReportRejectedTouch;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/analytics/SensorLoggerSession.java b/packages/SystemUI/src/com/android/systemui/analytics/SensorLoggerSession.java
index faaad2b..b39803a 100644
--- a/packages/SystemUI/src/com/android/systemui/analytics/SensorLoggerSession.java
+++ b/packages/SystemUI/src/com/android/systemui/analytics/SensorLoggerSession.java
@@ -53,6 +53,10 @@
mType = Session.REAL;
}
+ public void setType(int type) {
+ mType = type;
+ }
+
public void end(long endTimestampMillis, int result) {
mResult = result;
mEndTimestampMillis = endTimestampMillis;
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
index 1ac5992..664e886 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
@@ -22,6 +22,7 @@
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 @@
if (mHumanInteractionClassifier.isEnabled()) {
registerSensors(CLASSIFIER_SENSORS);
}
- if (mDataCollector.isEnabled()) {
+ if (mDataCollector.isEnabledFull()) {
registerSensors(COLLECTOR_SENSORS);
}
}
@@ -400,4 +401,15 @@
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();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index d1e9d9e..7c88307 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -1732,6 +1732,7 @@
// this to our ViewRootImpl.
mStatusBarKeyguardViewManager.getViewRootImpl().setReportNextDraw();
notifyDrawn(mDrawnCallback);
+ mDrawnCallback = null;
}
// only play "unlock" noises if not on a call (since the incall UI
@@ -1740,6 +1741,7 @@
playSounds(false);
}
+ mWakeAndUnlocking = false;
setShowingLocked(false);
mStatusBarKeyguardViewManager.hide(startTime, fadeoutDuration);
resetKeyguardDonePendingLocked();
@@ -1866,6 +1868,7 @@
synchronized (this) {
if (DEBUG) Log.d(TAG, "handleNotifyScreenTurnedOff");
mStatusBarKeyguardViewManager.onScreenTurnedOff();
+ mDrawnCallback = null;
mWakeAndUnlocking = false;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 0f4d9ed..51ff29e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -65,6 +65,7 @@
boolean mVertical;
boolean mScreenOn;
+ private int mCurrentRotation = -1;
boolean mShowMenu;
int mDisabledFlags = 0;
@@ -526,6 +527,10 @@
updateCurrentView();
}
+ public boolean needsReorient() {
+ return mCurrentRotation != mDisplay.getRotation();
+ }
+
private void updateCurrentView() {
final int rot = mDisplay.getRotation();
for (int i=0; i<4; i++) {
@@ -538,6 +543,7 @@
mButtonDisatchers.valueAt(i).setCurrentView(mCurrentView);
}
updateLayoutTransitionsEnabled();
+ mCurrentRotation = rot;
}
private void updateRecentsIcon() {
@@ -620,11 +626,12 @@
if (mCarMode && uiMode != Configuration.UI_MODE_TYPE_CAR) {
mCarMode = false;
uiCarModeChanged = true;
+ getHomeButton().setCarMode(mCarMode);
} else if (uiMode == Configuration.UI_MODE_TYPE_CAR) {
mCarMode = true;
uiCarModeChanged = true;
+ getHomeButton().setCarMode(mCarMode);
}
- getHomeButton().setCarMode(mCarMode);
}
return uiCarModeChanged;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 4f34ec2..d836c05 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -73,6 +73,7 @@
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.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 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 @@
private View mPendingRemoteInputView;
private View mPendingWorkRemoteInputView;
+ private View mReportRejectedTouch;
+
int mMaxAllowedKeyguardNotifications;
boolean mExpandedVisible;
@@ -929,6 +934,36 @@
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 @@
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)) {
@@ -3553,7 +3596,8 @@
@Override
public void onDisplayChanged(int displayId) {
- if (displayId == Display.DEFAULT_DISPLAY) {
+ if (displayId == Display.DEFAULT_DISPLAY
+ && mNavigationBarView != null && mNavigationBarView.needsReorient()) {
repositionNavigationBar();
}
}
@@ -4393,6 +4437,7 @@
mGroupManager.setStatusBarState(state);
mFalsingManager.setStatusBarState(state);
mStatusBarWindowManager.setStatusBarState(state);
+ updateReportRejectedTouchVisibility();
updateDozing();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/touch_analytics.proto b/packages/SystemUI/src/com/android/systemui/statusbar/phone/touch_analytics.proto
index afc8f77..50fd52a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/touch_analytics.proto
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/touch_analytics.proto
@@ -120,6 +120,7 @@
RESERVED_2 = 1;
RANDOM_WAKEUP = 2;
REAL = 3;
+ REJECTED_TOUCH_REPORT = 4;
}
optional uint64 startTimestampMillis = 1;
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index d9f2bac..5099db7 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -2203,6 +2203,10 @@
// System navigation key down.
ACTION_SYSTEM_NAVIGATION_KEY_DOWN = 494;
+ // OPEN: Settings > Display -> Ambient Display
+ // CATEGORY: SETTINGS
+ ACTION_AMBIENT_DISPLAY = 495;
+
// ---- End N-MR1 Constants, all N-MR1 constants go above this line ----
// Add new aosp constants above this line.
// END OF AOSP CONSTANTS
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index 2a7d945..fd93865 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -77,6 +77,9 @@
*/
static final int FLAG_FEATURE_INJECT_MOTION_EVENTS = 0x00000010;
+ static final int FEATURES_AFFECTING_MOTION_EVENTS = FLAG_FEATURE_INJECT_MOTION_EVENTS
+ | FLAG_FEATURE_AUTOCLICK | FLAG_FEATURE_TOUCH_EXPLORATION
+ | FLAG_FEATURE_SCREEN_MAGNIFIER;
/**
* Flag for enabling the feature to control the screen magnifier. If
* {@link #FLAG_FEATURE_SCREEN_MAGNIFIER} is set this flag is ignored
@@ -203,8 +206,13 @@
}
if (event instanceof MotionEvent) {
- MotionEvent motionEvent = (MotionEvent) event;
- processMotionEvent(state, motionEvent, policyFlags);
+ if ((mEnabledFeatures & FEATURES_AFFECTING_MOTION_EVENTS) != 0) {
+ MotionEvent motionEvent = (MotionEvent) event;
+ processMotionEvent(state, motionEvent, policyFlags);
+ return;
+ } else {
+ super.onInputEvent(event, policyFlags);
+ }
} else if (event instanceof KeyEvent) {
KeyEvent keyEvent = (KeyEvent) event;
processKeyEvent(state, keyEvent, policyFlags);
diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java
index 7ea8f1f..356ccb3 100644
--- a/services/core/java/com/android/server/PinnerService.java
+++ b/services/core/java/com/android/server/PinnerService.java
@@ -17,26 +17,23 @@
package com.android.server;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
-import android.content.res.Resources;
-import android.content.Intent;
-import android.util.EventLog;
-import android.util.Slog;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
-import android.os.Process;
+import android.os.UserHandle;
import android.provider.MediaStore;
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
import android.system.StructStat;
+import android.util.Slog;
import com.android.internal.app.ResolverActivity;
import com.android.internal.os.BackgroundThread;
@@ -44,12 +41,10 @@
import dalvik.system.DexFile;
import dalvik.system.VMRuntime;
-import java.util.ArrayList;
-import java.util.List;
import java.io.FileDescriptor;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
+import java.util.ArrayList;
/**
* <p>PinnerService pins important files for key processes in memory.</p>
@@ -89,20 +84,10 @@
}
mBinderService = new BinderService();
publishBinderService("pinner", mBinderService);
- mPinnerHandler.sendMessage(
- mPinnerHandler.obtainMessage(PinnerHandler.PIN_ONSTART_MSG));
- }
- /**
- * Pin camera on unlock.
- * We have to wait for unlock because the user's
- * preference for camera is not available from PackageManager until after
- * unlock
- */
- @Override
- public void onUnlockUser(int userHandle) {
- mPinnerHandler.sendMessage(
- mPinnerHandler.obtainMessage(PinnerHandler.PIN_CAMERA_MSG, userHandle, 0));
+ mPinnerHandler.obtainMessage(PinnerHandler.PIN_ONSTART_MSG).sendToTarget();
+ mPinnerHandler.obtainMessage(PinnerHandler.PIN_CAMERA_MSG, UserHandle.USER_SYSTEM, 0)
+ .sendToTarget();
}
/**
@@ -113,8 +98,7 @@
*/
@Override
public void onSwitchUser(int userHandle) {
- mPinnerHandler.sendMessage(
- mPinnerHandler.obtainMessage(PinnerHandler.PIN_CAMERA_MSG, userHandle, 0));
+ mPinnerHandler.obtainMessage(PinnerHandler.PIN_CAMERA_MSG, userHandle, 0).sendToTarget();
}
/**
@@ -194,8 +178,10 @@
// device without a fbe enabled, the _SECURE intent will never get set.
Intent cameraIntent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
PackageManager pm = mContext.getPackageManager();
- ResolveInfo cameraResolveInfo = pm.resolveActivityAsUser(
- cameraIntent, PackageManager.MATCH_DEFAULT_ONLY, userHandle);
+ ResolveInfo cameraResolveInfo = pm.resolveActivityAsUser(cameraIntent,
+ PackageManager.MATCH_DEFAULT_ONLY | PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
+ userHandle);
if (cameraResolveInfo == null ) {
//this is not necessarily an error
if (DEBUG) {
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index a3d2ebb..1bcff1a 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -748,7 +748,7 @@
if (sm != null) {
for (int i = sm.mServicesByName.size()-1; i >= 0; i--) {
ServiceRecord other = sm.mServicesByName.valueAt(i);
- if (other.foregroundId == r.foregroundId
+ if (other != r && other.foregroundId == r.foregroundId
&& other.packageName.equals(r.packageName)) {
// Found one! Abort the cancel.
return;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 87036cf..e336ed5 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2328,12 +2328,17 @@
ProcessRecord proc = r.app;
if (proc.vrThreadTid > 0) {
if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
- if (mInVrMode == true) {
- Process.setThreadScheduler(proc.vrThreadTid,
- Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
- } else {
- Process.setThreadScheduler(proc.vrThreadTid,
- Process.SCHED_OTHER, 0);
+ try {
+ if (mInVrMode == true) {
+ Process.setThreadScheduler(proc.vrThreadTid,
+ Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
+ } else {
+ Process.setThreadScheduler(proc.vrThreadTid,
+ Process.SCHED_OTHER, 0);
+ }
+ } catch (IllegalArgumentException e) {
+ Slog.e(TAG, "Failed to set scheduling policy, thread does"
+ + " not exist:\n" + e);
}
}
}
@@ -21942,6 +21947,11 @@
/*resultTo*/ null, bOptions, userId);
}
}
+
+ @Override
+ public int getUidProcessState(int uid) {
+ return getUidState(uid);
+ }
}
private final class SleepTokenImpl extends SleepToken {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 8b5942c..2dbbc88 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -180,7 +180,7 @@
= SystemProperties.getBoolean("debug.child_notifs", true);
static final int MAX_PACKAGE_NOTIFICATIONS = 50;
- static final float DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE = 50f;
+ static final float DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE = 10f;
// message codes
static final int MESSAGE_TIMEOUT = 2;
@@ -2538,20 +2538,32 @@
mUsageStats.registerEnqueuedByApp(pkg);
+
+ if (pkg == null || notification == null) {
+ throw new IllegalArgumentException("null not allowed: pkg=" + pkg
+ + " id=" + id + " notification=" + notification);
+ }
+ final StatusBarNotification n = new StatusBarNotification(
+ pkg, opPkg, id, tag, callingUid, callingPid, 0, notification,
+ user);
+
// Limit the number of notifications that any given package except the android
// package or a registered listener can enqueue. Prevents DOS attacks and deals with leaks.
if (!isSystemNotification && !isNotificationFromListener) {
synchronized (mNotificationList) {
- final float appEnqueueRate = mUsageStats.getAppEnqueueRate(pkg);
- if (appEnqueueRate > mMaxPackageEnqueueRate) {
- mUsageStats.registerOverRateQuota(pkg);
- final long now = SystemClock.elapsedRealtime();
- if ((now - mLastOverRateLogTime) > MIN_PACKAGE_OVERRATE_LOG_INTERVAL) {
- Slog.e(TAG, "Package enqueue rate is " + appEnqueueRate
- + ". Shedding events. package=" + pkg);
- mLastOverRateLogTime = now;
+ if(mNotificationsByKey.get(n.getKey()) != null) {
+ // this is an update, rate limit updates only
+ final float appEnqueueRate = mUsageStats.getAppEnqueueRate(pkg);
+ if (appEnqueueRate > mMaxPackageEnqueueRate) {
+ mUsageStats.registerOverRateQuota(pkg);
+ final long now = SystemClock.elapsedRealtime();
+ if ((now - mLastOverRateLogTime) > MIN_PACKAGE_OVERRATE_LOG_INTERVAL) {
+ Slog.e(TAG, "Package enqueue rate is " + appEnqueueRate
+ + ". Shedding events. package=" + pkg);
+ mLastOverRateLogTime = now;
+ }
+ return;
}
- return;
}
int count = 0;
@@ -2574,11 +2586,6 @@
}
}
- if (pkg == null || notification == null) {
- throw new IllegalArgumentException("null not allowed: pkg=" + pkg
- + " id=" + id + " notification=" + notification);
- }
-
// Whitelist pending intents.
if (notification.allPendingIntents != null) {
final int intentCount = notification.allPendingIntents.size();
@@ -2601,9 +2608,6 @@
Notification.PRIORITY_MAX);
// setup local book-keeping
- final StatusBarNotification n = new StatusBarNotification(
- pkg, opPkg, id, tag, callingUid, callingPid, 0, notification,
- user);
final NotificationRecord r = new NotificationRecord(getContext(), n);
mHandler.post(new EnqueueNotificationRunnable(userId, r));
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 8d400b5..558467b 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -20,6 +20,7 @@
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
import android.app.ActivityManagerNative;
import android.app.AppGlobals;
import android.app.IUidObserver;
@@ -284,6 +285,7 @@
private final PackageManagerInternal mPackageManagerInternal;
private final UserManager mUserManager;
private final UsageStatsManagerInternal mUsageStatsManagerInternal;
+ private final ActivityManagerInternal mActivityManagerInternal;
@GuardedBy("mLock")
final SparseIntArray mUidState = new SparseIntArray();
@@ -372,6 +374,8 @@
mUserManager = Preconditions.checkNotNull(context.getSystemService(UserManager.class));
mUsageStatsManagerInternal = Preconditions.checkNotNull(
LocalServices.getService(UsageStatsManagerInternal.class));
+ mActivityManagerInternal = Preconditions.checkNotNull(
+ LocalServices.getService(ActivityManagerInternal.class));
if (onlyForPackageManagerApis) {
return; // Don't do anything further. For unit tests only.
@@ -456,7 +460,8 @@
}
private boolean isProcessStateForeground(int processState) {
- return processState <= PROCESS_STATE_FOREGROUND_THRESHOLD;
+ return (processState != ActivityManager.PROCESS_STATE_NONEXISTENT)
+ && (processState <= PROCESS_STATE_FOREGROUND_THRESHOLD);
}
boolean isUidForegroundLocked(int uid) {
@@ -465,7 +470,13 @@
// so it's foreground anyway.
return true;
}
- return isProcessStateForeground(mUidState.get(uid, ActivityManager.MAX_PROCESS_STATE));
+ // First, check with the local cache.
+ if (isProcessStateForeground(mUidState.get(uid, ActivityManager.MAX_PROCESS_STATE))) {
+ return true;
+ }
+ // If the cache says background, reach out to AM. Since it'll internally need to hold
+ // the AM lock, we use it as a last resort.
+ return isProcessStateForeground(mActivityManagerInternal.getUidProcessState(uid));
}
long getUidLastForegroundElapsedTimeLocked(int uid) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 6451c74..b4085f5 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -11445,8 +11445,9 @@
for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
final WindowState win = windows.get(winNdx);
final boolean isForceHiding = mPolicy.isForceHiding(win.mAttrs);
+ final boolean keyguard = mPolicy.isKeyguardHostWindow(win.mAttrs);
if (win.isVisibleLw()
- && (win.mAppToken != null || isForceHiding)) {
+ && (win.mAppToken != null || isForceHiding || keyguard)) {
win.mWinAnimator.mDrawState = DRAW_PENDING;
// Force add to mResizingWindows.
win.mLastContentInsets.set(-1, -1, -1, -1);
diff --git a/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java b/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java
index 7a3b461..daaa4f5 100644
--- a/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java
+++ b/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java
@@ -67,10 +67,11 @@
void installApps(int userId) {
File[] files = preloadsAppsDirectory.listFiles();
+ AppInstallCounter counter = new AppInstallCounter(mContext, userId);
if (ArrayUtils.isEmpty(files)) {
+ counter.setExpectedAppsCount(0);
return;
}
- AppInstallCounter counter = new AppInstallCounter(mContext, userId);
int expectedCount = 0;
for (File file : files) {
String apkName = file.getName();
diff --git a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java b/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
index 8d5971f..7525e87 100644
--- a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
+++ b/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
@@ -340,9 +340,8 @@
UserHandle.SYSTEM);
Settings.Secure.putIntForUser(getContext().getContentResolver(),
Settings.Secure.SKIP_FIRST_USE_HINTS, 1, userInfo.id);
- Settings.Secure.putIntForUser(getContext().getContentResolver(),
- Settings.Global.PACKAGE_VERIFIER_ENABLE, 0, userInfo.id);
-
+ Settings.Global.putInt(getContext().getContentResolver(),
+ Settings.Global.PACKAGE_VERIFIER_ENABLE, 0);
grantRuntimePermissionToCamera(user);
clearPrimaryCallLog();
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index d003e56..e7f3345 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -36,6 +36,7 @@
import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.app.Activity;
+import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.IUidObserver;
import android.app.usage.UsageStatsManagerInternal;
@@ -715,6 +716,9 @@
return b(mRunningUsers.get(userId)) && b(mUnlockedUsers.get(userId));
}));
+ when(mMockActivityManagerInternal.getUidProcessState(anyInt())).thenReturn(
+ ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+
// User 0 and P0 are always running
mRunningUsers.put(USER_0, true);
mRunningUsers.put(USER_10, false);
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index df9242d..8560651 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -49,6 +49,7 @@
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.SomeArgs;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.FgThread;
@@ -320,6 +321,7 @@
private boolean mConnected;
private boolean mHostConnected;
private boolean mSourcePower;
+ private boolean mSinkPower;
private boolean mConfigured;
private boolean mUsbDataUnlocked;
private String mCurrentFunctions;
@@ -401,7 +403,18 @@
public void updateHostState(UsbPort port, UsbPortStatus status) {
boolean hostConnected = status.getCurrentDataRole() == UsbPort.DATA_ROLE_HOST;
boolean sourcePower = status.getCurrentPowerRole() == UsbPort.POWER_ROLE_SOURCE;
- obtainMessage(MSG_UPDATE_HOST_STATE, hostConnected ? 1 :0, sourcePower ? 1 :0).sendToTarget();
+ boolean sinkPower = status.getCurrentPowerRole() == UsbPort.POWER_ROLE_SINK;
+
+ if (DEBUG) {
+ Slog.i(TAG, "updateHostState " + port + " status=" + status);
+ }
+
+ SomeArgs args = SomeArgs.obtain();
+ args.argi1 = hostConnected ? 1 :0;
+ args.argi2 = sourcePower ? 1 :0;
+ args.argi3 = sinkPower ? 1 :0;
+
+ obtainMessage(MSG_UPDATE_HOST_STATE, args).sendToTarget();
}
private boolean waitForState(String state) {
@@ -718,8 +731,11 @@
}
break;
case MSG_UPDATE_HOST_STATE:
- mHostConnected = (msg.arg1 == 1);
- mSourcePower = (msg.arg2 == 1);
+ SomeArgs args = (SomeArgs) msg.obj;
+ mHostConnected = (args.argi1 == 1);
+ mSourcePower = (args.argi2 == 1);
+ mSinkPower = (args.argi3 == 1);
+ args.recycle();
updateUsbNotification();
if (mBootCompleted) {
updateUsbStateBroadcastIfNeeded();
@@ -809,6 +825,8 @@
}
} else if (mSourcePower) {
id = com.android.internal.R.string.usb_supplying_notification_title;
+ } else if (mHostConnected && mSinkPower) {
+ id = com.android.internal.R.string.usb_charging_notification_title;
}
if (id != mUsbNotificationId) {
// clear notification if title needs changing
@@ -908,6 +926,9 @@
pw.println(" mConfigured: " + mConfigured);
pw.println(" mUsbDataUnlocked: " + mUsbDataUnlocked);
pw.println(" mCurrentAccessory: " + mCurrentAccessory);
+ pw.println(" mHostConnected: " + mHostConnected);
+ pw.println(" mSourcePower: " + mSourcePower);
+ pw.println(" mSinkPower: " + mSinkPower);
try {
pw.println(" Kernel state: "
+ FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim());