Merge "Add a privileged permission to get user accounts" into mnc-dev
diff --git a/Android.mk b/Android.mk
index 121bc8e..a7a2ecb 100644
--- a/Android.mk
+++ b/Android.mk
@@ -285,7 +285,7 @@
core/java/com/android/internal/appwidget/IAppWidgetHost.aidl \
core/java/com/android/internal/backup/IBackupTransport.aidl \
core/java/com/android/internal/backup/IObbBackupService.aidl \
- core/java/com/android/internal/policy/IKeyguardShowCallback.aidl \
+ core/java/com/android/internal/policy/IKeyguardDrawnCallback.aidl \
core/java/com/android/internal/policy/IKeyguardExitCallback.aidl \
core/java/com/android/internal/policy/IKeyguardService.aidl \
core/java/com/android/internal/policy/IKeyguardStateCallback.aidl \
diff --git a/api/current.txt b/api/current.txt
index 8df19c0..462ca0a 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -9446,6 +9446,7 @@
method public java.lang.CharSequence loadDescription(android.content.pm.PackageManager);
field public static final android.os.Parcelable.Creator<android.content.pm.PermissionInfo> CREATOR;
field public static final int FLAG_COSTS_MONEY = 1; // 0x1
+ field public static final int FLAG_INSTALLED = 1073741824; // 0x40000000
field public static final int PROTECTION_DANGEROUS = 1; // 0x1
field public static final int PROTECTION_FLAG_APPOP = 64; // 0x40
field public static final int PROTECTION_FLAG_DEVELOPMENT = 32; // 0x20
@@ -28826,6 +28827,7 @@
method public void onHandleAssist(android.os.Bundle, android.app.assist.AssistStructure, android.app.assist.AssistContent);
method public void onHandleScreenshot(android.graphics.Bitmap);
method public void onHide();
+ method public void onLockscreenShown();
method public boolean onKeyDown(int, android.view.KeyEvent);
method public boolean onKeyLongPress(int, android.view.KeyEvent);
method public boolean onKeyMultiple(int, int, android.view.KeyEvent);
diff --git a/api/system-current.txt b/api/system-current.txt
index 9b5ffb9..d6e3c03 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -9784,6 +9784,7 @@
method public java.lang.CharSequence loadDescription(android.content.pm.PackageManager);
field public static final android.os.Parcelable.Creator<android.content.pm.PermissionInfo> CREATOR;
field public static final int FLAG_COSTS_MONEY = 1; // 0x1
+ field public static final int FLAG_INSTALLED = 1073741824; // 0x40000000
field public static final int PROTECTION_DANGEROUS = 1; // 0x1
field public static final int PROTECTION_FLAG_APPOP = 64; // 0x40
field public static final int PROTECTION_FLAG_DEVELOPMENT = 32; // 0x20
@@ -30978,6 +30979,7 @@
method public void onHandleAssist(android.os.Bundle, android.app.assist.AssistStructure, android.app.assist.AssistContent);
method public void onHandleScreenshot(android.graphics.Bitmap);
method public void onHide();
+ method public void onLockscreenShown();
method public boolean onKeyDown(int, android.view.KeyEvent);
method public boolean onKeyLongPress(int, android.view.KeyEvent);
method public boolean onKeyMultiple(int, int, android.view.KeyEvent);
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 9f4bc52..d952dfc 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -26,6 +26,7 @@
import android.app.IActivityManager;
import android.app.IInstrumentationWatcher;
import android.app.Instrumentation;
+import android.app.IStopUserCallback;
import android.app.ProfilerInfo;
import android.app.UiAutomationConnection;
import android.app.usage.ConfigurationStats;
@@ -133,7 +134,7 @@
" am to-app-uri [INTENT]\n" +
" am switch-user <USER_ID>\n" +
" am start-user <USER_ID>\n" +
- " am stop-user <USER_ID>\n" +
+ " am stop-user [-w] <USER_ID>\n" +
" am stack start <DISPLAY_ID> <INTENT>\n" +
" am stack movetask <TASK_ID> <STACK_ID> [true|false]\n" +
" am stack resize <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>\n" +
@@ -257,6 +258,7 @@
"\n" +
"am stop-user: stop execution of USER_ID, not allowing it to run any\n" +
" code until a later explicit start or switch to it.\n" +
+ " -w: wait for stop-user to complete.\n" +
"\n" +
"am stack start: start a new activity on <DISPLAY_ID> using <INTENT>.\n" +
"\n" +
@@ -1303,9 +1305,45 @@
}
}
+ private static class StopUserCallback extends IStopUserCallback.Stub {
+ private boolean mFinished = false;
+
+ public synchronized void waitForFinish() {
+ try {
+ while (!mFinished) wait();
+ } catch (InterruptedException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ @Override
+ public synchronized void userStopped(int userId) {
+ mFinished = true;
+ notifyAll();
+ }
+
+ @Override
+ public synchronized void userStopAborted(int userId) {
+ mFinished = true;
+ notifyAll();
+ }
+ }
+
private void runStopUser() throws Exception {
- String user = nextArgRequired();
- int res = mAm.stopUser(Integer.parseInt(user), null);
+ boolean wait = false;
+ String opt = null;
+ while ((opt = nextOption()) != null) {
+ if ("-w".equals(opt)) {
+ wait = true;
+ } else {
+ System.err.println("Error: unknown option: " + opt);
+ return;
+ }
+ }
+ int user = Integer.parseInt(nextArgRequired());
+ StopUserCallback callback = wait ? new StopUserCallback() : null;
+
+ int res = mAm.stopUser(user, callback);
if (res != ActivityManager.USER_OP_SUCCESS) {
String txt = "";
switch (res) {
@@ -1317,6 +1355,8 @@
break;
}
System.err.println("Switch failed: " + res + txt);
+ } else if (callback != null) {
+ callback.waitForFinish();
}
}
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 2dcd9cb..b39376c 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -16,6 +16,11 @@
package com.android.commands.pm;
+import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
+import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
+import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
+import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
+
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.IActivityManager;
@@ -212,6 +217,14 @@
return runSetPermissionEnforced();
}
+ if ("set-app-link".equals(op)) {
+ return runSetAppLink();
+ }
+
+ if ("get-app-link".equals(op)) {
+ return runGetAppLink();
+ }
+
if ("set-install-location".equals(op)) {
return runSetInstallLocation();
}
@@ -827,6 +840,148 @@
return Integer.toString(result);
}
+ // pm set-app-link [--user USER_ID] PACKAGE {always|ask|never|undefined}
+ private int runSetAppLink() {
+ int userId = UserHandle.USER_OWNER;
+
+ String opt;
+ while ((opt = nextOption()) != null) {
+ if (opt.equals("--user")) {
+ userId = Integer.parseInt(nextOptionData());
+ if (userId < 0) {
+ System.err.println("Error: user must be >= 0");
+ return 1;
+ }
+ } else {
+ System.err.println("Error: unknown option: " + opt);
+ showUsage();
+ return 1;
+ }
+ }
+
+ // Package name to act on; required
+ final String pkg = nextArg();
+ if (pkg == null) {
+ System.err.println("Error: no package specified.");
+ showUsage();
+ return 1;
+ }
+
+ // State to apply; {always|ask|never|undefined}, required
+ final String modeString = nextArg();
+ if (modeString == null) {
+ System.err.println("Error: no app link state specified.");
+ showUsage();
+ return 1;
+ }
+
+ final int newMode;
+ switch (modeString.toLowerCase()) {
+ case "undefined":
+ newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
+ break;
+
+ case "always":
+ newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
+ break;
+
+ case "ask":
+ newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
+ break;
+
+ case "never":
+ newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
+ break;
+
+ default:
+ System.err.println("Error: unknown app link state '" + modeString + "'");
+ return 1;
+ }
+
+ try {
+ final PackageInfo info = mPm.getPackageInfo(pkg, 0, userId);
+ if (info == null) {
+ System.err.println("Error: package " + pkg + " not found.");
+ return 1;
+ }
+
+ if ((info.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) {
+ System.err.println("Error: package " + pkg + " does not handle web links.");
+ return 1;
+ }
+
+ if (!mPm.updateIntentVerificationStatus(pkg, newMode, userId)) {
+ System.err.println("Error: unable to update app link status for " + pkg);
+ return 1;
+ }
+ } catch (Exception e) {
+ System.err.println(e.toString());
+ System.err.println(PM_NOT_RUNNING_ERR);
+ return 1;
+ }
+
+ return 0;
+ }
+
+ // pm get-app-link [--user USER_ID] PACKAGE
+ private int runGetAppLink() {
+ int userId = UserHandle.USER_OWNER;
+
+ String opt;
+ while ((opt = nextOption()) != null) {
+ if (opt.equals("--user")) {
+ userId = Integer.parseInt(nextOptionData());
+ if (userId < 0) {
+ System.err.println("Error: user must be >= 0");
+ return 1;
+ }
+ } else {
+ System.err.println("Error: unknown option: " + opt);
+ showUsage();
+ return 1;
+ }
+ }
+
+ // Package name to act on; required
+ final String pkg = nextArg();
+ if (pkg == null) {
+ System.err.println("Error: no package specified.");
+ showUsage();
+ return 1;
+ }
+
+ try {
+ final PackageInfo info = mPm.getPackageInfo(pkg, 0, userId);
+ if (info == null) {
+ System.err.println("Error: package " + pkg + " not found.");
+ return 1;
+ }
+
+ if ((info.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) {
+ System.err.println("Error: package " + pkg + " does not handle web links.");
+ return 1;
+ }
+
+ System.out.println(linkStateToString(mPm.getIntentVerificationStatus(pkg, userId)));
+ } catch (Exception e) {
+ System.err.println(e.toString());
+ System.err.println(PM_NOT_RUNNING_ERR);
+ return 1;
+ }
+
+ return 0;
+ }
+
+ private String linkStateToString(int state) {
+ switch (state) {
+ case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: return "undefined";
+ case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: return "ask";
+ case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: return "always";
+ case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER: return "never";
+ }
+ return "Unknown link state: " + state;
+ }
+
private int runSetInstallLocation() {
int loc;
@@ -1936,6 +2091,8 @@
System.err.println(" pm grant [--user USER_ID] PACKAGE PERMISSION");
System.err.println(" pm revoke [--user USER_ID] PACKAGE PERMISSION");
System.err.println(" pm reset-permissions");
+ System.err.println(" pm set-app-link [--user USER_ID] PACKAGE {always|ask|never|undefined}");
+ System.err.println(" pm get-app-link [--user USER_ID] PACKAGE");
System.err.println(" pm set-install-location [0/auto] [1/internal] [2/external]");
System.err.println(" pm get-install-location");
System.err.println(" pm set-permission-enforced PERMISSION [true|false]");
diff --git a/cmds/sm/src/com/android/commands/sm/Sm.java b/cmds/sm/src/com/android/commands/sm/Sm.java
index 0dad4dc..0a1ba4d1 100644
--- a/cmds/sm/src/com/android/commands/sm/Sm.java
+++ b/cmds/sm/src/com/android/commands/sm/Sm.java
@@ -81,6 +81,8 @@
runUnmount();
} else if ("format".equals(op)) {
runFormat();
+ } else if ("benchmark".equals(op)) {
+ runBenchmark();
} else if ("forget".equals(op)) {
runForget();
} else {
@@ -89,9 +91,12 @@
}
public void runListDisks() throws RemoteException {
+ final boolean onlyAdoptable = "adoptable".equals(nextArg());
final DiskInfo[] disks = mSm.getDisks();
for (DiskInfo disk : disks) {
- System.out.println(disk.getId());
+ if (!onlyAdoptable || disk.isAdoptable()) {
+ System.out.println(disk.getId());
+ }
}
}
@@ -161,6 +166,11 @@
mSm.format(volId);
}
+ public void runBenchmark() throws RemoteException {
+ final String volId = nextArg();
+ mSm.benchmark(volId);
+ }
+
public void runForget() throws RemoteException{
final String fsUuid = nextArg();
if ("all".equals(fsUuid)) {
@@ -180,7 +190,7 @@
}
private static int showUsage() {
- System.err.println("usage: sm list-disks");
+ System.err.println("usage: sm list-disks [adoptable]");
System.err.println(" sm list-volumes [public|private|emulated|all]");
System.err.println(" sm has-adoptable");
System.err.println(" sm get-primary-storage-uuid");
@@ -190,6 +200,7 @@
System.err.println(" sm mount VOLUME");
System.err.println(" sm unmount VOLUME");
System.err.println(" sm format VOLUME");
+ System.err.println(" sm benchmark VOLUME");
System.err.println("");
System.err.println(" sm forget [UUID|all]");
System.err.println("");
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index 13030ca..84cbea9 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -1094,8 +1094,10 @@
container.getViewTreeObserver().removeOnPreDrawListener(this);
// Don't include any newly-hidden fragments in the transition.
- excludeHiddenFragments(hiddenFragmentViews, inFragment.mContainerId,
- overallTransition);
+ if (inFragment != null) {
+ excludeHiddenFragments(hiddenFragmentViews, inFragment.mContainerId,
+ overallTransition);
+ }
ArrayMap<String, View> namedViews = null;
if (sharedElementTransition != null) {
@@ -1692,7 +1694,7 @@
private static void setNameOverrides(TransitionState state, ArrayList<String> sourceNames,
ArrayList<String> targetNames) {
- if (sourceNames != null) {
+ if (sourceNames != null && targetNames != null) {
for (int i = 0; i < sourceNames.size(); i++) {
String source = sourceNames.get(i);
String target = targetNames.get(i);
@@ -1703,7 +1705,9 @@
private void setBackNameOverrides(TransitionState state, ArrayMap<String, View> namedViews,
boolean isEnd) {
- int count = mSharedElementTargetNames == null ? 0 : mSharedElementTargetNames.size();
+ int targetCount = mSharedElementTargetNames == null ? 0 : mSharedElementTargetNames.size();
+ int sourceCount = mSharedElementSourceNames == null ? 0 : mSharedElementSourceNames.size();
+ final int count = Math.min(targetCount, sourceCount);
for (int i = 0; i < count; i++) {
String source = mSharedElementSourceNames.get(i);
String originalTarget = mSharedElementTargetNames.get(i);
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
index e09ab56..2ba87744 100644
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -79,6 +79,10 @@
* delivered through {@code callback}.
* <p>
* Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+ * An app must hold
+ * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
+ * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission
+ * in order to get results.
*
* @param callback Callback used to deliver scan results.
* @throws IllegalArgumentException If {@code callback} is null.
@@ -95,6 +99,10 @@
* Start Bluetooth LE scan. The scan results will be delivered through {@code callback}.
* <p>
* Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+ * An app must hold
+ * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
+ * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission
+ * in order to get results.
*
* @param filters {@link ScanFilter}s for finding exact BLE devices.
* @param settings Settings for the scan.
diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java
index 2828d83..d514513 100644
--- a/core/java/android/content/pm/PermissionInfo.java
+++ b/core/java/android/content/pm/PermissionInfo.java
@@ -145,12 +145,10 @@
public static final int FLAG_COSTS_MONEY = 1<<0;
/**
- * Flag for {@link #protectionLevel}, corresponding
- * to the <code>hide</code> value of
- * {@link android.R.attr#permissionFlags}.
- * @hide
+ * Flag for {@link #flags}, indicating that this permission has been
+ * installed into the system's globally defined permissions.
*/
- public static final int PROTECTION_FLAG_HIDE = 1<<1;
+ public static final int FLAG_INSTALLED = 1<<30;
/**
* Additional flags about this permission as given by
@@ -210,6 +208,15 @@
if ((level&PermissionInfo.PROTECTION_FLAG_PRE23) != 0) {
protLevel += "|pre23";
}
+ if ((level&PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0) {
+ protLevel += "|installer";
+ }
+ if ((level&PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0) {
+ protLevel += "|verifier";
+ }
+ if ((level&PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0) {
+ protLevel += "|preinstalled";
+ }
return protLevel;
}
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index c5f142a..ee37047 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -321,6 +321,14 @@
* Called when a fingerprint is valid but not recognized.
*/
public void onAuthenticationFailed() { }
+
+ /**
+ * Called when a fingerprint image has been acquired, but wasn't processed yet.
+ *
+ * @param acquireInfo one of FINGERPRINT_ACQUIRED_* constants
+ * @hide
+ */
+ public void onAuthenticationAcquired(int acquireInfo) {}
};
/**
@@ -737,9 +745,13 @@
}
private void sendAcquiredResult(long deviceId, int acquireInfo) {
+ if (mAuthenticationCallback != null) {
+ mAuthenticationCallback.onAuthenticationAcquired(acquireInfo);
+ }
final String msg = getAcquiredString(acquireInfo);
- if (msg == null) return;
-
+ if (msg == null) {
+ return;
+ }
if (mEnrollmentCallback != null) {
mEnrollmentCallback.onEnrollmentHelp(acquireInfo, msg);
} else if (mAuthenticationCallback != null) {
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 864225a..af4c2bc 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -16,6 +16,7 @@
package android.os;
+import android.annotation.NonNull;
import android.provider.DocumentsContract.Document;
import android.system.ErrnoException;
import android.system.Os;
@@ -69,6 +70,8 @@
/** Regular expression for safe filenames: no spaces or metacharacters */
private static final Pattern SAFE_FILENAME_PATTERN = Pattern.compile("[\\w%+,./=_-]+");
+ private static final File[] EMPTY = new File[0];
+
/**
* Set owner and mode of of given {@link File}.
*
@@ -634,4 +637,13 @@
return new File(parent, name + "." + ext);
}
}
+
+ public static @NonNull File[] listFilesOrEmpty(File dir) {
+ File[] res = dir.listFiles();
+ if (res != null) {
+ return res;
+ } else {
+ return EMPTY;
+ }
+ }
}
diff --git a/core/java/android/os/IDeviceIdleController.aidl b/core/java/android/os/IDeviceIdleController.aidl
index b768852..d3eec1e 100644
--- a/core/java/android/os/IDeviceIdleController.aidl
+++ b/core/java/android/os/IDeviceIdleController.aidl
@@ -29,5 +29,6 @@
boolean isPowerSaveWhitelistApp(String name);
void addPowerSaveTempWhitelistApp(String name, long duration, int userId, String reason);
long addPowerSaveTempWhitelistAppForMms(String name, int userId, String reason);
+ long addPowerSaveTempWhitelistAppForSms(String name, int userId, String reason);
void exitIdle(String reason);
}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index b104135..79fb805 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -45,7 +45,9 @@
private final Context mContext;
/**
- * Specifies if a user is disallowed from adding and removing accounts.
+ * Specifies if a user is disallowed from adding and removing accounts, unless they are
+ * {@link android.accounts.AccountManager#addAccountExplicitly programmatically} added by
+ * Authenticator.
* The default value is <code>false</code>.
*
* <p/>Key for user restrictions.
diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java
index bae5455..04d5952 100644
--- a/core/java/android/security/keymaster/KeymasterDefs.java
+++ b/core/java/android/security/keymaster/KeymasterDefs.java
@@ -51,6 +51,7 @@
public static final int KM_TAG_DIGEST = KM_ENUM_REP | 5;
public static final int KM_TAG_PADDING = KM_ENUM_REP | 6;
public static final int KM_TAG_CALLER_NONCE = KM_BOOL | 7;
+ public static final int KM_TAG_MIN_MAC_LENGTH = KM_UINT | 8;
public static final int KM_TAG_RESCOPING_ADD = KM_ENUM_REP | 101;
public static final int KM_TAG_RESCOPING_DEL = KM_ENUM_REP | 102;
@@ -194,6 +195,9 @@
public static final int KM_ERROR_KEY_RATE_LIMIT_EXCEEDED = -54;
public static final int KM_ERROR_CALLER_NONCE_PROHIBITED = -55;
public static final int KM_ERROR_KEY_MAX_OPS_EXCEEDED = -56;
+ public static final int KM_ERROR_INVALID_MAC_LENGTH = -57;
+ public static final int KM_ERROR_MISSING_MIN_MAC_LENGTH = -58;
+ public static final int KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH = -59;
public static final int KM_ERROR_UNIMPLEMENTED = -100;
public static final int KM_ERROR_VERSION_MISMATCH = -101;
public static final int KM_ERROR_UNKNOWN_ERROR = -1000;
@@ -237,6 +241,8 @@
sErrorCodeToString.put(KM_ERROR_INVALID_NONCE, "Invalid IV");
sErrorCodeToString.put(KM_ERROR_CALLER_NONCE_PROHIBITED,
"Caller-provided IV not permitted");
+ sErrorCodeToString.put(KM_ERROR_INVALID_MAC_LENGTH,
+ "Invalid MAC or authentication tag length");
sErrorCodeToString.put(KM_ERROR_UNIMPLEMENTED, "Not implemented");
sErrorCodeToString.put(KM_ERROR_UNKNOWN_ERROR, "Unknown error");
}
diff --git a/core/java/android/service/voice/IVoiceInteractionSession.aidl b/core/java/android/service/voice/IVoiceInteractionSession.aidl
index 8fe84e1..dbc28f7 100644
--- a/core/java/android/service/voice/IVoiceInteractionSession.aidl
+++ b/core/java/android/service/voice/IVoiceInteractionSession.aidl
@@ -35,5 +35,6 @@
void taskStarted(in Intent intent, int taskId);
void taskFinished(in Intent intent, int taskId);
void closeSystemDialogs();
+ void onLockscreenShown();
void destroy();
}
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index f08e93c..f647aa6 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -265,6 +265,11 @@
}
@Override
+ public void onLockscreenShown() {
+ mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_ON_LOCKSCREEN_SHOWN));
+ }
+
+ @Override
public void destroy() {
mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_DESTROY));
}
@@ -674,6 +679,7 @@
static final int MSG_HANDLE_SCREENSHOT = 105;
static final int MSG_SHOW = 106;
static final int MSG_HIDE = 107;
+ static final int MSG_ON_LOCKSCREEN_SHOWN = 108;
class MyCallbacks implements HandlerCaller.Callback, SoftInputWindow.Callback {
@Override
@@ -752,6 +758,10 @@
if (DEBUG) Log.d(TAG, "doHide");
doHide();
break;
+ case MSG_ON_LOCKSCREEN_SHOWN:
+ if (DEBUG) Log.d(TAG, "onLockscreenShown");
+ onLockscreenShown();
+ break;
}
if (args != null) {
args.recycle();
@@ -1296,6 +1306,13 @@
hide();
}
+ /**
+ * Called when the lockscreen was shown.
+ */
+ public void onLockscreenShown() {
+ hide();
+ }
+
@Override
public void onConfigurationChanged(Configuration newConfig) {
}
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index dac02fa..6a561e6 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -731,7 +731,8 @@
// Negative values in a mySize value in RelativeLayout
// measurement is code for, "we got an unspecified mode in the
// RelativeLayout's measure spec."
- if (mySize < 0 && !mAllowBrokenMeasureSpecs) {
+ final boolean isUnspecified = mySize < 0;
+ if (isUnspecified && !mAllowBrokenMeasureSpecs) {
if (childStart != VALUE_NOT_SET && childEnd != VALUE_NOT_SET) {
// Constraints fixed both edges, so child has an exact size.
childSpecSize = Math.max(0, childEnd - childStart);
@@ -767,7 +768,7 @@
if (childStart != VALUE_NOT_SET && childEnd != VALUE_NOT_SET) {
// Constraints fixed both edges, so child must be an exact size.
- childSpecMode = MeasureSpec.EXACTLY;
+ childSpecMode = isUnspecified ? MeasureSpec.UNSPECIFIED : MeasureSpec.EXACTLY;
childSpecSize = Math.max(0, maxAvailable);
} else {
if (childSize >= 0) {
@@ -784,7 +785,7 @@
} else if (childSize == LayoutParams.MATCH_PARENT) {
// Child wanted to be as big as possible. Give all available
// space.
- childSpecMode = MeasureSpec.EXACTLY;
+ childSpecMode = isUnspecified ? MeasureSpec.UNSPECIFIED : MeasureSpec.EXACTLY;
childSpecSize = Math.max(0, maxAvailable);
} else if (childSize == LayoutParams.WRAP_CONTENT) {
// Child wants to wrap content. Use AT_MOST to communicate
diff --git a/core/java/com/android/internal/app/AssistUtils.java b/core/java/com/android/internal/app/AssistUtils.java
index 0910daf..d552e54 100644
--- a/core/java/com/android/internal/app/AssistUtils.java
+++ b/core/java/com/android/internal/app/AssistUtils.java
@@ -122,6 +122,16 @@
}
}
+ public void onLockscreenShown() {
+ try {
+ if (mVoiceInteractionManagerService != null) {
+ mVoiceInteractionManagerService.onLockscreenShown();
+ }
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to call onLockscreenShown", e);
+ }
+ }
+
public ComponentName getAssistComponentForUser(int userId) {
final String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(),
Settings.Secure.ASSISTANT, userId);
diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
index dc946abc..1a963f3 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
@@ -131,4 +131,9 @@
* from the lockscreen.
*/
boolean activeServiceSupportsLaunchFromKeyguard();
+
+ /**
+ * Called when the lockscreen got shown.
+ */
+ void onLockscreenShown();
}
diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java
index cbe535f..91ae27b 100644
--- a/core/java/com/android/internal/logging/MetricsLogger.java
+++ b/core/java/com/android/internal/logging/MetricsLogger.java
@@ -27,7 +27,20 @@
*/
public class MetricsLogger implements MetricsConstants {
// Temporary constants go here, to await migration to MetricsConstants.
- // next value is 227;
+ // next value is 238;
+
+ public static final int TUNER = 227;
+ public static final int TUNER_QS = 228;
+ public static final int TUNER_DEMO_MODE = 229;
+
+ public static final int TUNER_QS_REORDER = 230;
+ public static final int TUNER_QS_ADD = 231;
+ public static final int TUNER_QS_REMOVE = 232;
+ public static final int TUNER_STATUS_BAR_ENABLE = 233;
+ public static final int TUNER_STATUS_BAR_DISABLE = 234;
+ public static final int TUNER_DEMO_MODE_ENABLED = 235;
+ public static final int TUNER_DEMO_MODE_ON = 236;
+ public static final int TUNER_BATTERY_PERCENTAGE = 237;
public static void visible(Context context, int category) throws IllegalArgumentException {
if (Build.IS_DEBUGGABLE && category == VIEW_UNKNOWN) {
diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java
index 264b8c1..9caf78a 100644
--- a/core/java/com/android/internal/os/BatteryStatsHelper.java
+++ b/core/java/com/android/internal/os/BatteryStatsHelper.java
@@ -47,6 +47,7 @@
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
+import java.util.Locale;
/**
* A helper class for retrieving the power usage information for all applications and services.
@@ -267,15 +268,20 @@
public static String makemAh(double power) {
if (power == 0) return "0";
- else if (power < .00001) return String.format("%.8f", power);
- else if (power < .0001) return String.format("%.7f", power);
- else if (power < .001) return String.format("%.6f", power);
- else if (power < .01) return String.format("%.5f", power);
- else if (power < .1) return String.format("%.4f", power);
- else if (power < 1) return String.format("%.3f", power);
- else if (power < 10) return String.format("%.2f", power);
- else if (power < 100) return String.format("%.1f", power);
- else return String.format("%.0f", power);
+
+ final String format;
+ if (power < .00001) format = "%.8f";
+ else if (power < .0001) format = "%.7f";
+ else if (power < .001) format = "%.6f";
+ else if (power < .01) format = "%.5f";
+ else if (power < .1) format = "%.4f";
+ else if (power < 1) format = "%.3f";
+ else if (power < 10) format = "%.2f";
+ else if (power < 100) format = "%.1f";
+ else format = "%.0f";
+
+ // Use English locale because this is never used in UI (only in checkin and dump).
+ return String.format(Locale.ENGLISH, format, power);
}
/**
diff --git a/core/java/com/android/internal/os/KernelWakelockReader.java b/core/java/com/android/internal/os/KernelWakelockReader.java
index 768d586..0369c3f 100644
--- a/core/java/com/android/internal/os/KernelWakelockReader.java
+++ b/core/java/com/android/internal/os/KernelWakelockReader.java
@@ -68,12 +68,12 @@
try {
FileInputStream is;
try {
- is = new FileInputStream(sWakeupSourceFile);
- wakeup_sources = true;
+ is = new FileInputStream(sWakelockFile);
+ wakeup_sources = false;
} catch (java.io.FileNotFoundException e) {
try {
- is = new FileInputStream(sWakelockFile);
- wakeup_sources = false;
+ is = new FileInputStream(sWakeupSourceFile);
+ wakeup_sources = true;
} catch (java.io.FileNotFoundException e2) {
return null;
}
diff --git a/core/java/com/android/internal/policy/IKeyguardShowCallback.aidl b/core/java/com/android/internal/policy/IKeyguardDrawnCallback.aidl
similarity index 89%
rename from core/java/com/android/internal/policy/IKeyguardShowCallback.aidl
rename to core/java/com/android/internal/policy/IKeyguardDrawnCallback.aidl
index a2784d9..ef8478c 100644
--- a/core/java/com/android/internal/policy/IKeyguardShowCallback.aidl
+++ b/core/java/com/android/internal/policy/IKeyguardDrawnCallback.aidl
@@ -15,6 +15,6 @@
*/
package com.android.internal.policy;
-oneway interface IKeyguardShowCallback {
- void onShown(IBinder windowToken);
+oneway interface IKeyguardDrawnCallback {
+ void onDrawn();
}
diff --git a/core/java/com/android/internal/policy/IKeyguardService.aidl b/core/java/com/android/internal/policy/IKeyguardService.aidl
index 7ab4651..79af452 100644
--- a/core/java/com/android/internal/policy/IKeyguardService.aidl
+++ b/core/java/com/android/internal/policy/IKeyguardService.aidl
@@ -15,7 +15,7 @@
*/
package com.android.internal.policy;
-import com.android.internal.policy.IKeyguardShowCallback;
+import com.android.internal.policy.IKeyguardDrawnCallback;
import com.android.internal.policy.IKeyguardStateCallback;
import com.android.internal.policy.IKeyguardExitCallback;
@@ -57,7 +57,13 @@
/**
* Called when the device has started waking up.
*/
- void onStartedWakingUp(IKeyguardShowCallback callback);
+ void onStartedWakingUp();
+
+ /**
+ * Called when the device screen is turning on.
+ */
+ void onScreenTurningOn(IKeyguardDrawnCallback callback);
+
void setKeyguardEnabled(boolean enabled);
void onSystemReady();
void doKeyguardTimeout(in Bundle options);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 5324c70..3e22e09 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -331,7 +331,7 @@
<!-- Used for runtime permissions related to user's contacts and profile. -->
<permission-group android:name="android.permission-group.CONTACTS"
- android:icon="@drawable/perm_group_social_info"
+ android:icon="@drawable/perm_group_contacts"
android:label="@string/permgrouplab_contacts"
android:description="@string/permgroupdesc_contacts"
android:priority="100" />
@@ -391,7 +391,7 @@
<!-- Used for runtime permissions related to user's SMS messages. -->
<permission-group android:name="android.permission-group.SMS"
- android:icon="@drawable/perm_group_messages"
+ android:icon="@drawable/perm_group_sms"
android:label="@string/permgrouplab_sms"
android:description="@string/permgroupdesc_sms"
android:priority="300" />
@@ -729,6 +729,7 @@
<!-- Used for permissions that are associated with accessing
camera or capturing images/video from the device. -->
<permission-group android:name="android.permission-group.SENSORS"
+ android:icon="@drawable/perm_group_sensors"
android:label="@string/permgrouplab_sensors"
android:description="@string/permgroupdesc_sensors"
android:priority="800" />
@@ -1535,7 +1536,9 @@
<permission android:name="android.permission.CHANGE_CONFIGURATION"
android:protectionLevel="signature|privileged|development" />
- <!-- Allows an application to read or write the system settings. -->
+ <!-- Allows an application to read or write the system settings.
+ <p>Protection level: signature
+ -->
<permission android:name="android.permission.WRITE_SETTINGS"
android:label="@string/permlab_writeSettings"
android:description="@string/permdesc_writeSettings"
diff --git a/core/res/res/drawable/ic_more_items.xml b/core/res/res/drawable/ic_more_items.xml
new file mode 100644
index 0000000..5fdcdce
--- /dev/null
+++ b/core/res/res/drawable/ic_more_items.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 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.
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm4 4h14v-2H7v2zm0 4h14v-2H7v2zM7
+7v2h14V7H7z" />
+ <path
+ android:pathData="M0 0h24v24H0z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/perm_group_calendar.xml b/core/res/res/drawable/perm_group_calendar.xml
index a0f9dd2..4dc7b37 100644
--- a/core/res/res/drawable/perm_group_calendar.xml
+++ b/core/res/res/drawable/perm_group_calendar.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015 The Android Open Source Project
@@ -14,11 +15,15 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24.0dp"
- android:height="24.0dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
<path
- android:fillColor="#FF000000"
- android:pathData="M34.0,24.0L24.0,24.0l0.0,10.0l10.0,0.0L34.0,24.0zM32.0,2.0l0.0,4.0L16.0,6.0L16.0,2.0l-4.0,0.0l0.0,4.0l-2.0,0.0c-2.21,0.0 -3.98,1.79 -3.98,4.0L6.0,38.0c0.0,2.21 1.79,4.0 4.0,4.0l28.0,0.0c2.21,0.0 4.0,-1.79 4.0,-4.0L42.0,10.0c0.0,-2.21 -1.79,-4.0 -4.0,-4.0l-2.0,0.0L36.0,2.0l-4.0,0.0zm6.0,36.0L10.0,38.0L10.0,16.0l28.0,0.0l0.0,22.0z"/>
-</vector>
+ android:fillColor="#000000"
+ android:pathData="M17 12h-5v5h5v-5zM16 1v2H8V1H6v2H5c-1.11 0-1.99 .9 -1.99 2L3 19c0 1.1 .89 2 2
+2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2h-1V1h-2zm3 18H5V8h14v11z" />
+ <path
+ android:pathData="M0 0h24v24H0z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/perm_group_camera.xml b/core/res/res/drawable/perm_group_camera.xml
index 30d31ce..741a40e 100644
--- a/core/res/res/drawable/perm_group_camera.xml
+++ b/core/res/res/drawable/perm_group_camera.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015 The Android Open Source Project
@@ -14,11 +15,19 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24.0dp"
- android:height="24.0dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
<path
- android:fillColor="#FF000000"
- android:pathData="M18.8,21.0l9.53,-16.51C26.94,4.18 25.49,4.0 24.0,4.0c-4.8,0.0 -9.19,1.69 -12.64,4.51l7.33,12.6 0.11,-0.2zm24.28,-3.0c-1.84,-5.85 -6.3,-10.52 -11.99,-12.68L23.77,18.0l19.31,0.0zm0.52,2.0L28.62,20.0l0.58,1.0 9.53,16.5C41.99,33.94 44.0,29.21 44.0,24.0c0.0,-1.37 -0.14,-2.71 -0.4,-4.0zm-26.53,4.0l-7.8,-13.5C6.01,14.06 4.0,18.79 4.0,24.0c0.0,1.3 0.14,2.7 0.4,4.0l14.98,0.0l-2.31,-4.0zM4.92,30.0c1.84,5.85 6.3,10.52 11.99,12.68L24.23,30.0L4.92,30.0zm22.54,0.0l-7.8,13.51c1.0,0.31 2.8,0.49 4.3,0.49 4.8,0.0 9.19,-1.69 12.64,-4.51L29.31,26.8 27.46,30.0z"/>
-</vector>
+ android:fillColor="#000000"
+ android:pathData="M 12 8.8 C 13.7673111995 8.8 15.2 10.2326888005 15.2 12 C 15.2 13.7673111995 13.7673111995 15.2 12 15.2 C 10.2326888005 15.2 8.8 13.7673111995 8.8 12 C 8.8 10.2326888005 10.2326888005 8.8 12 8.8 Z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M9 2L7.17 4H4c-1.1 0-2 .9-2 2v12c0 1.1 .9 2 2 2h16c1.1 0 2-.9
+2-2V6c0-1.1-.9-2-2-2h-3.17L15 2H9zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5
+5-2.24 5-5 5z" />
+ <path
+ android:pathData="M0 0h24v24H0z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/perm_group_contacts.xml b/core/res/res/drawable/perm_group_contacts.xml
new file mode 100644
index 0000000..d698fd1
--- /dev/null
+++ b/core/res/res/drawable/perm_group_contacts.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 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.
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M0 0h24v24H0zm0 0h24v24H0zm0 0h24v24H0z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M20 0H4v2h16V0zM4 24h16v-2H4v2zM20 4H4c-1.1 0-2 .9-2 2v12c0 1.1 .9 2 2 2h16c1.1
+0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 2.75c1.24 0 2.25 1.01 2.25 2.25s-1.01 2.25-2.25
+2.25S9.75 10.24 9.75 9 10.76 6.75 12 6.75zM17 17H7v-1.5c0-1.67 3.33-2.5 5-2.5s5
+.83 5 2.5V17z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/perm_group_location.xml b/core/res/res/drawable/perm_group_location.xml
index 4184cf9..fbc6066 100644
--- a/core/res/res/drawable/perm_group_location.xml
+++ b/core/res/res/drawable/perm_group_location.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015 The Android Open Source Project
@@ -14,11 +15,15 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24.0dp"
- android:height="24.0dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
<path
- android:fillColor="#FF000000"
- android:pathData="M24.0,16.0c-4.42,0.0 -8.0,3.58 -8.0,8.0s3.58,8.0 8.0,8.0 8.0,-3.58 8.0,-8.0 -3.58,-8.0 -8.0,-8.0zm17.88,6.0C40.96,13.66 34.34,7.04 26.0,6.12L26.0,2.0l-4.0,0.0l0.0,4.12C13.66,7.04 7.04,13.66 6.12,22.0L2.0,22.0l0.0,4.0l4.12,0.0c0.92,8.34 7.54,14.96 15.88,15.88L22.0,46.0l4.0,0.0l0.0,-4.12c8.34,-0.92 14.96,-7.54 15.88,-15.88L46.0,26.0l0.0,-4.0l-4.12,0.0zM24.0,38.0c-7.73,0.0 -14.0,-6.27 -14.0,-14.0s6.27,-14.0 14.0,-14.0 14.0,6.27 14.0,14.0 -6.27,14.0 -14.0,14.0z"/>
-</vector>
+ android:fillColor="#000000"
+ android:pathData="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0
+9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z" />
+ <path
+ android:pathData="M0 0h24v24H0z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/perm_group_messages.xml b/core/res/res/drawable/perm_group_messages.xml
deleted file mode 100644
index 4140e6c..0000000
--- a/core/res/res/drawable/perm_group_messages.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
- Copyright (C) 2015 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.
- 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24.0dp"
- android:height="24.0dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
- <path
- android:fillColor="#FF000000"
- android:pathData="M40.0,4.0L8.0,4.0C5.79,4.0 4.02,5.79 4.02,8.0L4.0,44.0l8.0,-8.0l28.0,0.0c2.21,0.0 4.0,-1.79 4.0,-4.0L44.0,8.0c0.0,-2.21 -1.79,-4.0 -4.0,-4.0zm-4.0,24.0L12.0,28.0l0.0,-4.0l16.0,0.0l0.0,4.0zm0.0,-6.0L12.0,22.0l0.0,-4.0l24.0,0.0l0.0,4.0zm0.0,-6.0L12.0,16.0l0.0,-4.0l24.0,0.0l0.0,4.0z"/>
-</vector>
diff --git a/core/res/res/drawable/perm_group_microphone.xml b/core/res/res/drawable/perm_group_microphone.xml
index 670ef98..c565d20 100644
--- a/core/res/res/drawable/perm_group_microphone.xml
+++ b/core/res/res/drawable/perm_group_microphone.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015 The Android Open Source Project
@@ -14,11 +15,16 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24.0dp"
- android:height="24.0dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
<path
- android:fillColor="#FF000000"
- android:pathData="M24.0,28.0c3.31,0.0 5.98,-2.69 5.98,-6.0L30.0,10.0c0.0,-3.32 -2.68,-6.0 -6.0,-6.0 -3.31,0.0 -6.0,2.68 -6.0,6.0l0.0,12.0c0.0,3.31 2.69,6.0 6.0,6.0zm10.6,-6.0c0.0,6.0 -5.07,10.2 -10.6,10.2 -5.52,0.0 -10.6,-4.2 -10.6,-10.2L10.0,22c0.0,6.83 5.44,12.47 12.0,13.44L22.0,42.0l4.0,0.0l0.0,-6.56c6.56,-0.97 12.0,-6.61 12.0,-13.44l-3.4,0.0z"/>
-</vector>
+ android:fillColor="#000000"
+ android:pathData="M12 14c1.66 0 2.99-1.34 2.99-3L15 5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3
+3 3zm5.3-3c0 3-2.54 5.1-5.3 5.1S6.7 14 6.7 11H5c0 3.41 2.72 6.23 6
+6.72V21h2v-3.28c3.28-.48 6-3.3 6-6.72h-1.7z" />
+ <path
+ android:pathData="M0 0h24v24H0z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/perm_group_phone_calls.xml b/core/res/res/drawable/perm_group_phone_calls.xml
index 04ac6b9..a647894 100644
--- a/core/res/res/drawable/perm_group_phone_calls.xml
+++ b/core/res/res/drawable/perm_group_phone_calls.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015 The Android Open Source Project
@@ -14,11 +15,17 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24.0dp"
- android:height="24.0dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
<path
- android:fillColor="#FF000000"
- android:pathData="M13.25,21.59c2.88,5.66 7.51,10.29 13.18,13.17l4.4,-4.41c0.55,-0.55 1.34,-0.71 2.03,-0.49C35.1,30.6 37.51,31.0 40.0,31.0c1.11,0.0 2.0,0.89 2.0,2.0l0.0,7.0c0.0,1.11 -0.89,2.0 -2.0,2.0C21.22,42.0 6.0,26.78 6.0,8.0c0.0,-1.1 0.9,-2.0 2.0,-2.0l7.0,0.0c1.11,0.0 2.0,0.89 2.0,2.0 0.0,2.4 0.4,4.9 1.14,7.1 0.2,0.6 0.06,1.48 -0.49,2.03l-4.4,4.42z"/>
-</vector>
+ android:pathData="M0 0h24v24H0z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27 .67 -.36 1.02-.24 1.12
+.37 2.33 .57 3.57 .57 .55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17
+0-.55 .45 -1 1-1h3.5c.55 0 1 .45 1 1 0 1.25 .2 2.45 .57 3.57 .11 .35 .03 .74-.25
+1.02l-2.2 2.2z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/perm_group_sensors.xml b/core/res/res/drawable/perm_group_sensors.xml
new file mode 100644
index 0000000..ce36c13
--- /dev/null
+++ b/core/res/res/drawable/perm_group_sensors.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 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.
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M13.49 5.48c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm-3.6 13.9l1-4.4 2.1
+2v6h2v-7.5l-2.1-2 .6-3c1.3 1.5 3.3 2.5 5.5 2.5v-2c-1.9
+0-3.5-1-4.3-2.4l-1-1.6c-.4-.6-1-1-1.7-1-.3 0-.5 .1 -.8 .1 l-5.2
+2.2v4.7h2v-3.4l1.8-.7-1.6 8.1-4.9-1-.4 2 7 1.4z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/perm_group_sms.xml b/core/res/res/drawable/perm_group_sms.xml
new file mode 100644
index 0000000..9b32c601
--- /dev/null
+++ b/core/res/res/drawable/perm_group_sms.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 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.
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M20 2H4c-1.1 0-1.99 .9 -1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM9
+11H7V9h2v2zm4 0h-2V9h2v2zm4 0h-2V9h2v2z" />
+ <path
+ android:pathData="M0 0h24v24H0z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/perm_group_social_info.xml b/core/res/res/drawable/perm_group_social_info.xml
deleted file mode 100644
index f0f7a90..0000000
--- a/core/res/res/drawable/perm_group_social_info.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
- Copyright (C) 2015 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.
- 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24.0dp"
- android:height="24.0dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
- <path
- android:fillColor="#FF000000"
- android:pathData="M32.0,22.0c3.31,0.0 5.98,-2.69 5.98,-6.0s-2.67,-6.0 -5.98,-6.0c-3.31,0.0 -6.0,2.69 -6.0,6.0s2.69,6.0 6.0,6.0zm-16.0,0.0c3.31,0.0 5.98,-2.69 5.98,-6.0s-2.67,-6.0 -5.98,-6.0c-3.31,0.0 -6.0,2.69 -6.0,6.0s2.69,6.0 6.0,6.0zm0.0,4.0c-4.67,0.0 -14.0,2.34 -14.0,7.0l0.0,5.0l28.0,0.0l0.0,-5.0c0.0,-4.66 -9.33,-7.0 -14.0,-7.0zm16.0,0.0c-0.58,0.0 -1.2,0.04 -1.9,0.11C32.39,27.78 34.0,30.03 34.0,33.0l0.0,5.0l12.0,0.0l0.0,-5.0c0.0,-4.66 -9.33,-7.0 -14.0,-7.0z"/>
-</vector>
diff --git a/core/res/res/drawable/perm_group_storage.xml b/core/res/res/drawable/perm_group_storage.xml
index 74f16d8..477270d 100644
--- a/core/res/res/drawable/perm_group_storage.xml
+++ b/core/res/res/drawable/perm_group_storage.xml
@@ -1,7 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
<!--
-Copyright (C) 2015 The Android Open Source Project
+ Copyright (C) 2015 The Android Open Source Project
- Licensed under the Apache License, Version 2.0 (the "License");
+ 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
@@ -14,11 +15,15 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
<path
- android:pathData="M20,8H8c-2.2,0 -4,1.8 -4,4l0,24c0,2.2 1.8,4 4,4h32c2.2,0 4,-1.8 4,-4V16c0,-2.2 -1.8,-4 -4,-4H24L20,8z"
- android:fillColor="#FFFFFF"/>
-</vector>
+ android:fillColor="#000000"
+ android:pathData="M10 4H4c-1.1 0-1.99 .9 -1.99 2L2 18c0 1.1 .9 2 2 2h16c1.1 0 2-.9
+2-2V8c0-1.1-.9-2-2-2h-8l-2-2z" />
+ <path
+ android:pathData="M0 0h24v24H0z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 06b6389..54848e9 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -408,6 +408,7 @@
<integer translatable="false" name="config_wifi_framework_wifi_score_good_link_speed_24">24</integer>
<integer translatable="false" name="config_wifi_framework_wifi_score_good_link_speed_5">36</integer>
<string translatable="false" name="config_wifi_random_mac_oui">DA-A1-19</string>
+ <string translatable="false" name="config_wifi_framework_sap_2G_channel_list">1,6,11</string>
<bool translatable="false" name="config_wifi_framework_cellular_handover_enable_user_triggered_adjustment">true</bool>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index f590ebe..8070986 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -337,6 +337,7 @@
<java-symbol type="integer" name="config_wifi_active_rx_cur_ma" />
<java-symbol type="integer" name="config_wifi_tx_cur_ma" />
<java-symbol type="integer" name="config_wifi_operating_voltage_mv" />
+ <java-symbol type="string" name="config_wifi_framework_sap_2G_channel_list" />
<java-symbol type="bool" name="editable_voicemailnumber" />
@@ -2313,4 +2314,6 @@
<java-symbol type="bool" name="config_eap_sim_based_auth_supported" />
<java-symbol type="array" name="config_cell_retries_per_error_code" />
+ <java-symbol type="drawable" name="ic_more_items" />
+
</resources>
diff --git a/docs/html/design/wear/structure.jd b/docs/html/design/wear/structure.jd
index c1d9ef9..768aa7f 100644
--- a/docs/html/design/wear/structure.jd
+++ b/docs/html/design/wear/structure.jd
@@ -166,8 +166,11 @@
<li>A map that asks the user to drop a pin should exit when the pin is dropped.</li>
<li>A short game can exit when the game finishes.</li>
<li>A drawing app can finish after 5 seconds of inactivity.</li>
+
+ <p class="note">An app generally should not exit in {@link android.app.Activity#onPause onPause()}. This is because events such as <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html#Heads-up">Heads-up Notifications</a> can trigger the {@link android.app.Activity#onPause() onPause()} callback.</p>
</ul>
+
<h3>Manually exiting</h3>
<p>Even with logical exit points like these, some cases may exist where the user may want to
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java
index 5459bea..441ee66 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java
@@ -51,7 +51,7 @@
abstract class AndroidKeyStoreAuthenticatedAESCipherSpi extends AndroidKeyStoreCipherSpiBase {
abstract static class GCM extends AndroidKeyStoreAuthenticatedAESCipherSpi {
- private static final int MIN_SUPPORTED_TAG_LENGTH_BITS = 96;
+ static final int MIN_SUPPORTED_TAG_LENGTH_BITS = 96;
private static final int MAX_SUPPORTED_TAG_LENGTH_BITS = 128;
private static final int DEFAULT_TAG_LENGTH_BITS = 128;
private static final int IV_LENGTH_BYTES = 12;
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
index fd014eb..4c174f1 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
@@ -171,7 +171,7 @@
"Key size must be positive: " + mKeySizeBits);
} else if ((mKeySizeBits % 8) != 0) {
throw new InvalidAlgorithmParameterException(
- "Key size in must be a multiple of 8: " + mKeySizeBits);
+ "Key size must be a multiple of 8: " + mKeySizeBits);
}
try {
@@ -272,6 +272,11 @@
KeymasterUtils.addUserAuthArgs(args,
spec.isUserAuthenticationRequired(),
spec.getUserAuthenticationValidityDurationSeconds());
+ KeymasterUtils.addMinMacLengthAuthorizationIfNecessary(
+ args,
+ mKeymasterAlgorithm,
+ mKeymasterBlockModes,
+ mKeymasterDigests);
args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, spec.getKeyValidityStart());
args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
spec.getKeyValidityForOriginationEnd());
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
index 88858de..915d86f 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
@@ -672,6 +672,11 @@
KeymasterUtils.addUserAuthArgs(args,
params.isUserAuthenticationRequired(),
params.getUserAuthenticationValidityDurationSeconds());
+ KeymasterUtils.addMinMacLengthAuthorizationIfNecessary(
+ args,
+ keymasterAlgorithm,
+ keymasterBlockModes,
+ keymasterDigests);
args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME,
params.getKeyValidityStart());
args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
diff --git a/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java b/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java
index ea0f4b9..dbb79bc 100644
--- a/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java
+++ b/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java
@@ -19,12 +19,14 @@
import android.os.IBinder;
import android.security.KeyStore;
import android.security.KeyStoreException;
+import android.security.keymaster.KeymasterDefs;
import android.security.keymaster.OperationResult;
import libcore.util.EmptyArray;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.security.ProviderException;
/**
* Helper for streaming a crypto operation's input and output via {@link KeyStore} service's
@@ -135,14 +137,15 @@
mBuffered = EmptyArray.BYTE;
mBufferedOffset = 0;
mBufferedLength = 0;
- } else if (opResult.inputConsumed == 0) {
+ } else if (opResult.inputConsumed <= 0) {
// Nothing was consumed. More input needed.
if (inputLength > 0) {
// More input is available, but it wasn't included into the previous chunk
// because the chunk reached its maximum permitted size.
// Shouldn't have happened.
- throw new IllegalStateException("Nothing consumed from max-sized chunk: "
- + chunk.length + " bytes");
+ throw new KeyStoreException(KeymasterDefs.KM_ERROR_UNKNOWN_ERROR,
+ "Keystore consumed nothing from max-sized chunk: " + chunk.length
+ + " bytes");
}
mBuffered = chunk;
mBufferedOffset = 0;
@@ -153,8 +156,9 @@
mBufferedOffset = opResult.inputConsumed;
mBufferedLength = chunk.length - opResult.inputConsumed;
} else {
- throw new IllegalStateException("Consumed more than provided: "
- + opResult.inputConsumed + ", provided: " + chunk.length);
+ throw new KeyStoreException(KeymasterDefs.KM_ERROR_UNKNOWN_ERROR,
+ "Keystore consumed more input than provided. Provided: " + chunk.length
+ + ", consumed: " + opResult.inputConsumed);
}
if ((opResult.output != null) && (opResult.output.length > 0)) {
@@ -165,7 +169,7 @@
try {
bufferedOutput.write(opResult.output);
} catch (IOException e) {
- throw new IllegalStateException("Failed to buffer output", e);
+ throw new ProviderException("Failed to buffer output", e);
}
}
} else {
@@ -179,7 +183,7 @@
try {
bufferedOutput.write(opResult.output);
} catch (IOException e) {
- throw new IllegalStateException("Failed to buffer output", e);
+ throw new ProviderException("Failed to buffer output", e);
}
result = bufferedOutput.toByteArray();
}
@@ -229,27 +233,71 @@
return EmptyArray.BYTE;
}
- byte[] chunk = ArrayUtils.subarray(mBuffered, mBufferedOffset, mBufferedLength);
- mBuffered = EmptyArray.BYTE;
- mBufferedLength = 0;
- mBufferedOffset = 0;
+ // Keep invoking the update operation with remaining buffered data until either all of the
+ // buffered data is consumed or until update fails to consume anything.
+ ByteArrayOutputStream bufferedOutput = null;
+ while (mBufferedLength > 0) {
+ byte[] chunk = ArrayUtils.subarray(mBuffered, mBufferedOffset, mBufferedLength);
+ OperationResult opResult = mKeyStoreStream.update(chunk);
+ if (opResult == null) {
+ throw new KeyStoreConnectException();
+ } else if (opResult.resultCode != KeyStore.NO_ERROR) {
+ throw KeyStore.getKeyStoreException(opResult.resultCode);
+ }
- OperationResult opResult = mKeyStoreStream.update(chunk);
- if (opResult == null) {
- throw new KeyStoreConnectException();
- } else if (opResult.resultCode != KeyStore.NO_ERROR) {
- throw KeyStore.getKeyStoreException(opResult.resultCode);
+ if (opResult.inputConsumed <= 0) {
+ // Nothing was consumed. Break out of the loop to avoid an infinite loop.
+ break;
+ }
+
+ if (opResult.inputConsumed >= chunk.length) {
+ // All of the input was consumed
+ mBuffered = EmptyArray.BYTE;
+ mBufferedOffset = 0;
+ mBufferedLength = 0;
+ } else {
+ // Some of the input was not consumed
+ mBuffered = chunk;
+ mBufferedOffset = opResult.inputConsumed;
+ mBufferedLength = chunk.length - opResult.inputConsumed;
+ }
+
+ if (opResult.inputConsumed > chunk.length) {
+ throw new KeyStoreException(KeymasterDefs.KM_ERROR_UNKNOWN_ERROR,
+ "Keystore consumed more input than provided. Provided: "
+ + chunk.length + ", consumed: " + opResult.inputConsumed);
+ }
+
+ if ((opResult.output != null) && (opResult.output.length > 0)) {
+ // Some output was produced by this update operation
+ if (bufferedOutput == null) {
+ // No output buffered yet.
+ if (mBufferedLength == 0) {
+ // No more output will be produced by this flush operation
+ mProducedOutputSizeBytes += opResult.output.length;
+ return opResult.output;
+ } else {
+ // More output might be produced by this flush operation -- buffer output.
+ bufferedOutput = new ByteArrayOutputStream();
+ }
+ }
+ // Buffer the output from this update operation
+ try {
+ bufferedOutput.write(opResult.output);
+ } catch (IOException e) {
+ throw new ProviderException("Failed to buffer output", e);
+ }
+ }
}
- if (opResult.inputConsumed < chunk.length) {
- throw new IllegalStateException("Keystore failed to consume all input. Provided: "
- + chunk.length + ", consumed: " + opResult.inputConsumed);
- } else if (opResult.inputConsumed > chunk.length) {
- throw new IllegalStateException("Keystore consumed more input than provided"
- + " . Provided: " + chunk.length + ", consumed: " + opResult.inputConsumed);
+ if (mBufferedLength > 0) {
+ throw new KeyStoreException(KeymasterDefs.KM_ERROR_INVALID_INPUT_LENGTH,
+ "Keystore failed to consume last "
+ + ((mBufferedLength != 1) ? (mBufferedLength + " bytes") : "byte")
+ + " of input");
}
- byte[] result = (opResult.output != null) ? opResult.output : EmptyArray.BYTE;
+ byte[] result = (bufferedOutput != null) ? bufferedOutput.toByteArray() : EmptyArray.BYTE;
mProducedOutputSizeBytes += result.length;
return result;
}
diff --git a/keystore/java/android/security/keystore/KeymasterUtils.java b/keystore/java/android/security/keystore/KeymasterUtils.java
index 92d636c..feafbfa 100644
--- a/keystore/java/android/security/keystore/KeymasterUtils.java
+++ b/keystore/java/android/security/keystore/KeymasterUtils.java
@@ -22,6 +22,8 @@
import android.security.keymaster.KeymasterArguments;
import android.security.keymaster.KeymasterDefs;
+import java.security.ProviderException;
+
/**
* @hide
*/
@@ -133,4 +135,45 @@
userAuthenticationValidityDurationSeconds);
}
}
+
+ /**
+ * Adds {@code KM_TAG_MIN_MAC_LENGTH} tag, if necessary, to the keymaster arguments for
+ * generating or importing a key. This tag may only be needed for symmetric keys (e.g., HMAC,
+ * AES-GCM).
+ */
+ public static void addMinMacLengthAuthorizationIfNecessary(KeymasterArguments args,
+ int keymasterAlgorithm,
+ int[] keymasterBlockModes,
+ int[] keymasterDigests) {
+ switch (keymasterAlgorithm) {
+ case KeymasterDefs.KM_ALGORITHM_AES:
+ if (com.android.internal.util.ArrayUtils.contains(
+ keymasterBlockModes, KeymasterDefs.KM_MODE_GCM)) {
+ // AES GCM key needs the minimum length of AEAD tag specified.
+ args.addUnsignedInt(KeymasterDefs.KM_TAG_MIN_MAC_LENGTH,
+ AndroidKeyStoreAuthenticatedAESCipherSpi.GCM
+ .MIN_SUPPORTED_TAG_LENGTH_BITS);
+ }
+ break;
+ case KeymasterDefs.KM_ALGORITHM_HMAC:
+ // HMAC key needs the minimum length of MAC set to the output size of the associated
+ // digest. This is because we do not offer a way to generate shorter MACs and
+ // don't offer a way to verify MACs (other than by generating them).
+ if (keymasterDigests.length != 1) {
+ throw new ProviderException(
+ "Unsupported number of authorized digests for HMAC key: "
+ + keymasterDigests.length
+ + ". Exactly one digest must be authorized");
+ }
+ int keymasterDigest = keymasterDigests[0];
+ int digestOutputSizeBits = getDigestOutputSizeBits(keymasterDigest);
+ if (digestOutputSizeBits == -1) {
+ throw new ProviderException(
+ "HMAC key authorized for unsupported digest: "
+ + KeyProperties.Digest.fromKeymaster(keymasterDigest));
+ }
+ args.addUnsignedInt(KeymasterDefs.KM_TAG_MIN_MAC_LENGTH, digestOutputSizeBits);
+ break;
+ }
+ }
}
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 80f349a..0951fc1 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -214,10 +214,10 @@
info.renderer->pushLayerUpdate(mLayer);
}
- if (CC_UNLIKELY(info.canvasContext)) {
- // If canvasContext is not null that means there are prefetched layers
- // that need to be accounted for. That might be us, so tell CanvasContext
- // that this layer is in the tree and should not be destroyed.
+ if (info.canvasContext) {
+ // There might be prefetched layers that need to be accounted for.
+ // That might be us, so tell CanvasContext that this layer is in the
+ // tree and should not be destroyed.
info.canvasContext->markLayerInUse(this);
}
}
@@ -339,7 +339,8 @@
TextureCache& cache = Caches::getInstance().textureCache;
info.out.hasFunctors |= subtree->functors.size();
for (size_t i = 0; info.prepareTextures && i < subtree->bitmapResources.size(); i++) {
- info.prepareTextures = cache.prefetchAndMarkInUse(subtree->bitmapResources[i]);
+ info.prepareTextures = cache.prefetchAndMarkInUse(
+ info.canvasContext, subtree->bitmapResources[i]);
}
for (size_t i = 0; i < subtree->children().size(); i++) {
DrawRenderNodeOp* op = subtree->children()[i];
diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h
index 7227ce0..4bcd96d 100644
--- a/libs/hwui/Texture.h
+++ b/libs/hwui/Texture.h
@@ -97,7 +97,7 @@
* Whether or not the Texture is marked in use and thus not evictable for
* the current frame. This is reset at the start of a new frame.
*/
- bool isInUse = false;
+ void* isInUse = nullptr;
private:
/**
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index 2a90087..fda0091 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -122,10 +122,12 @@
mAssetAtlas = assetAtlas;
}
-void TextureCache::resetMarkInUse() {
+void TextureCache::resetMarkInUse(void* ownerToken) {
LruCache<uint32_t, Texture*>::Iterator iter(mCache);
while (iter.next()) {
- iter.value()->isInUse = false;
+ if (iter.value()->isInUse == ownerToken) {
+ iter.value()->isInUse = nullptr;
+ }
}
}
@@ -189,10 +191,10 @@
return texture;
}
-bool TextureCache::prefetchAndMarkInUse(const SkBitmap* bitmap) {
+bool TextureCache::prefetchAndMarkInUse(void* ownerToken, const SkBitmap* bitmap) {
Texture* texture = getCachedTexture(bitmap, AtlasUsageType::Use);
if (texture) {
- texture->isInUse = true;
+ texture->isInUse = ownerToken;
}
return texture;
}
diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h
index 83c6e91..7a7ee5a 100644
--- a/libs/hwui/TextureCache.h
+++ b/libs/hwui/TextureCache.h
@@ -66,14 +66,14 @@
/**
* Resets all Textures to not be marked as in use
*/
- void resetMarkInUse();
+ void resetMarkInUse(void* ownerToken);
/**
* Attempts to precache the SkBitmap. Returns true if a Texture was successfully
* acquired for the bitmap, false otherwise. If a Texture was acquired it is
* marked as in use.
*/
- bool prefetchAndMarkInUse(const SkBitmap* bitmap);
+ bool prefetchAndMarkInUse(void* ownerToken, const SkBitmap* bitmap);
/**
* Returns the texture associated with the specified bitmap from either within the cache, or
diff --git a/libs/hwui/TreeInfo.h b/libs/hwui/TreeInfo.h
index 0799c6c..ed853f7 100644
--- a/libs/hwui/TreeInfo.h
+++ b/libs/hwui/TreeInfo.h
@@ -95,7 +95,7 @@
// layer updates or similar. May be NULL.
OpenGLRenderer* renderer;
ErrorHandler* errorHandler;
- // TODO: Remove this? May be NULL
+ // May be NULL (TODO: can it really?)
renderthread::CanvasContext* canvasContext;
struct Out {
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 09f93b8..e472e93 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -178,16 +178,13 @@
info.damageAccumulator = &mDamageAccumulator;
info.renderer = mCanvas;
- if (mPrefetechedLayers.size() && info.mode == TreeInfo::MODE_FULL) {
- info.canvasContext = this;
- }
+ info.canvasContext = this;
+
mAnimationContext->startFrame(info.mode);
mRootRenderNode->prepareTree(info);
mAnimationContext->runRemainingAnimations(info);
- if (info.canvasContext) {
- freePrefetechedLayers();
- }
+ freePrefetechedLayers();
if (CC_UNLIKELY(!mNativeWindow.get())) {
mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame);
@@ -369,7 +366,11 @@
if (mEglManager.hasEglContext()) {
freePrefetechedLayers();
mRootRenderNode->destroyHardwareResources();
- Caches::getInstance().flush(Caches::kFlushMode_Layers);
+ Caches& caches = Caches::getInstance();
+ // Make sure to release all the textures we were owning as there won't
+ // be another draw
+ caches.textureCache.resetMarkInUse(this);
+ caches.flush(Caches::kFlushMode_Layers);
}
}
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index 6507ce8..a4ac13b 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -114,7 +114,7 @@
int64_t vsync = mFrameInfo[static_cast<int>(FrameInfoIndex::Vsync)];
mRenderThread->timeLord().vsyncReceived(vsync);
mContext->makeCurrent();
- Caches::getInstance().textureCache.resetMarkInUse();
+ Caches::getInstance().textureCache.resetMarkInUse(mContext);
for (size_t i = 0; i < mLayers.size(); i++) {
mContext->processLayerUpdate(mLayers[i].get());
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardConstants.java b/packages/Keyguard/src/com/android/keyguard/KeyguardConstants.java
index e5f3dc9..3927122 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardConstants.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardConstants.java
@@ -27,4 +27,5 @@
*/
public static final boolean DEBUG = false;
public static final boolean DEBUG_SIM_STATES = false;
+ public static final boolean DEBUG_FP_WAKELOCK = true;
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 9e5644e..b098258 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -44,7 +44,9 @@
import android.os.Handler;
import android.os.IRemoteCallback;
import android.os.Message;
+import android.os.PowerManager;
import android.os.RemoteException;
+import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
@@ -90,12 +92,15 @@
private static final String TAG = "KeyguardUpdateMonitor";
private static final boolean DEBUG = KeyguardConstants.DEBUG;
private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
+ private static final boolean DEBUG_FP_WAKELOCK = KeyguardConstants.DEBUG_FP_WAKELOCK;
private static final int LOW_BATTERY_THRESHOLD = 20;
+ private static final long FINGERPRINT_WAKELOCK_TIMEOUT_MS = 15 * 1000;
private static final String ACTION_FACE_UNLOCK_STARTED
= "com.android.facelock.FACE_UNLOCK_STARTED";
private static final String ACTION_FACE_UNLOCK_STOPPED
= "com.android.facelock.FACE_UNLOCK_STOPPED";
+ private static final String FINGERPRINT_WAKE_LOCK_NAME = "wake-and-unlock wakelock";
// Callback messages
private static final int MSG_TIME_UPDATE = 301;
@@ -114,10 +119,6 @@
private static final int MSG_SCREEN_TURNED_ON = 319;
private static final int MSG_SCREEN_TURNED_OFF = 320;
private static final int MSG_KEYGUARD_BOUNCER_CHANGED = 322;
- private static final int MSG_FINGERPRINT_AUTHENTICATED = 323;
- private static final int MSG_FINGERPRINT_ERROR = 324;
- private static final int MSG_FINGERPRINT_HELP = 325;
- private static final int MSG_FINGERPRINT_AUTH_FAILED = 326;
private static final int MSG_FACE_UNLOCK_STATE_CHANGED = 327;
private static final int MSG_SIM_SUBSCRIPTION_INFO_CHANGED = 328;
private static final int MSG_AIRPLANE_MODE_CHANGED = 329;
@@ -157,6 +158,7 @@
private List<SubscriptionInfo> mSubscriptionInfo;
private boolean mFingerprintDetectionRunning;
private TrustManager mTrustManager;
+ private PowerManager mPowerManager;
private final Handler mHandler = new Handler() {
@Override
@@ -210,18 +212,6 @@
case MSG_SCREEN_TURNED_ON:
handleScreenTurnedOn();
break;
- case MSG_FINGERPRINT_AUTHENTICATED:
- handleFingerprintAuthenticated();
- break;
- case MSG_FINGERPRINT_HELP:
- handleFingerprintHelp(msg.arg1 /* msgId */, (String) msg.obj /* errString */);
- break;
- case MSG_FINGERPRINT_ERROR:
- handleFingerprintError(msg.arg1 /* msgId */, (String) msg.obj /* errString */);
- break;
- case MSG_FINGERPRINT_AUTH_FAILED:
- handleFingerprintAuthFailed();
- break;
case MSG_FACE_UNLOCK_STATE_CHANGED:
handleFaceUnlockStateChanged(msg.arg1 != 0, msg.arg2);
break;
@@ -253,6 +243,8 @@
private static int sCurrentUser;
+ private boolean mWakeAndUnlocking;
+
public synchronized static void setCurrentUser(int currentUser) {
sCurrentUser = currentUser;
}
@@ -353,23 +345,72 @@
}
}
- private void onFingerprintAuthenticated(int userId) {
+ private void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) {
mUserFingerprintAuthenticated.put(userId, true);
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
- cb.onFingerprintAuthenticated(userId);
+ cb.onFingerprintAuthenticated(userId, wakeAndUnlocking);
}
}
}
private void handleFingerprintAuthFailed() {
+ releaseFingerprintWakeLock();
stopListeningForFingerprint();
handleFingerprintHelp(-1, mContext.getString(R.string.fingerprint_not_recognized));
updateFingerprintListeningState();
}
+ private void handleFingerprintAcquired(int acquireInfo) {
+ if (acquireInfo != FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) {
+ return;
+ }
+ if (!mScreenOn) {
+ releaseFingerprintWakeLock();
+ mWakeLock = mPowerManager.newWakeLock(
+ PowerManager.PARTIAL_WAKE_LOCK, FINGERPRINT_WAKE_LOCK_NAME);
+ mWakeLock.acquire();
+ mWakeAndUnlocking = true;
+ if (DEBUG_FP_WAKELOCK) {
+ Log.i(TAG, "fingerprint acquired, grabbing fp wakelock");
+ }
+ mHandler.postDelayed(mReleaseFingerprintWakeLockRunnable,
+ FINGERPRINT_WAKELOCK_TIMEOUT_MS);
+ } else {
+ mWakeAndUnlocking = false;
+ }
+ }
+
+ private final Runnable mReleaseFingerprintWakeLockRunnable = new Runnable() {
+ @Override
+ public void run() {
+ if (DEBUG_FP_WAKELOCK) {
+ Log.i(TAG, "fp wakelock: TIMEOUT!!");
+ }
+ releaseFingerprintWakeLock();
+ }
+ };
+
+ private void releaseFingerprintWakeLock() {
+ if (mWakeLock != null) {
+ mHandler.removeCallbacks(mReleaseFingerprintWakeLockRunnable);
+ if (DEBUG_FP_WAKELOCK) {
+ Log.i(TAG, "releasing fp wakelock");
+ }
+ mWakeLock.release();
+ mWakeLock = null;
+ }
+ }
+
private void handleFingerprintAuthenticated() {
+ if (mWakeAndUnlocking) {
+ if (DEBUG_FP_WAKELOCK) {
+ Log.i(TAG, "fp wakelock: Authenticated, waking up...");
+ }
+ mPowerManager.wakeUp(SystemClock.uptimeMillis());
+ }
+ releaseFingerprintWakeLock();
try {
final int userId;
try {
@@ -382,7 +423,7 @@
Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId);
return;
}
- onFingerprintAuthenticated(userId);
+ onFingerprintAuthenticated(userId, mWakeAndUnlocking);
} finally {
setFingerprintRunningDetectionRunning(false);
}
@@ -555,26 +596,32 @@
@Override
public void onAuthenticationFailed() {
- mHandler.obtainMessage(MSG_FINGERPRINT_AUTH_FAILED).sendToTarget();
+ handleFingerprintAuthFailed();
};
@Override
public void onAuthenticationSucceeded(AuthenticationResult result) {
- mHandler.obtainMessage(MSG_FINGERPRINT_AUTHENTICATED).sendToTarget();
+ handleFingerprintAuthenticated();
}
@Override
public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
- mHandler.obtainMessage(MSG_FINGERPRINT_HELP, helpMsgId, 0, helpString).sendToTarget();
+ handleFingerprintHelp(helpMsgId, helpString.toString());
}
@Override
public void onAuthenticationError(int errMsgId, CharSequence errString) {
- mHandler.obtainMessage(MSG_FINGERPRINT_ERROR, errMsgId, 0, errString).sendToTarget();
+ handleFingerprintError(errMsgId, errString.toString());
+ }
+
+ @Override
+ public void onAuthenticationAcquired(int acquireInfo) {
+ handleFingerprintAcquired(acquireInfo);
}
};
private CancellationSignal mFingerprintCancelSignal;
private FingerprintManager mFpm;
+ private PowerManager.WakeLock mWakeLock;
/**
* When we receive a
@@ -741,6 +788,7 @@
private KeyguardUpdateMonitor(Context context) {
mContext = context;
mSubscriptionManager = SubscriptionManager.from(context);
+ mPowerManager = context.getSystemService(PowerManager.class);
mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
// Since device can't be un-provisioned, we only need to register a content observer
// to update mDeviceProvisioned when we are...
@@ -819,7 +867,7 @@
}
private boolean shouldListenForFingerprint() {
- return mScreenOn && mKeyguardIsVisible && !mSwitchingUser
+ return mKeyguardIsVisible && !mSwitchingUser
&& mTrustManager.hasUserAuthenticatedSinceBoot(ActivityManager.getCurrentUser());
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index 26e6973..9fd8d30 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -178,8 +178,10 @@
/**
* Called when a fingerprint is recognized.
* @param userId the user id for which the fingerprint was authenticated
+ * @param wakeAndUnlocking whether the authentication woke the device up and thus we'd like to
+ * dismiss the lockscreen before turning on the screen
*/
- public void onFingerprintAuthenticated(int userId) { }
+ public void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) { }
/**
* Called when fingerprint provides help string (e.g. "Try again")
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 6e5dc3f..fea7f94 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -405,5 +405,13 @@
android:exported="true"
android:singleUser="true"
android:permission="android.permission.BIND_DREAM_SERVICE" />
+
+ <receiver
+ android:name=".tuner.TunerService$ClearReceiver"
+ android:exported="false">
+ <intent-filter>
+ <action android:name="com.android.systemui.action.CLEAR_TUNER" />
+ </intent-filter>
+ </receiver>
</application>
</manifest>
diff --git a/packages/SystemUI/res/drawable-nodpi/tuner.xml b/packages/SystemUI/res/drawable-nodpi/tuner.xml
index e27423f..0596aa4 100644
--- a/packages/SystemUI/res/drawable-nodpi/tuner.xml
+++ b/packages/SystemUI/res/drawable-nodpi/tuner.xml
@@ -1,7 +1,7 @@
<!--
- Copyright (C) 2015 The Android Open Source Project
+ Copyright (C) 2015 The Android Open Source Project
- Licensed under the Apache License, Version 2.0 (the "License");
+ 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
@@ -14,14 +14,11 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="48.0dp"
- android:height="48.0dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
+ android:width="24.0dp"
+ android:height="24.0dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
<path
- android:fillColor="#FF000000"
- android:pathData="M29.9,24.8c0.0,-0.3 0.1,-0.5 0.1,-0.8s0.0,-0.5 -0.1,-0.8l1.7,-1.3c0.2,-0.1 0.2,-0.3 0.1,-0.5l-1.6,-2.8c-0.1,-0.2 -0.3,-0.2 -0.5,-0.2l-2.0,0.8c-0.4,-0.3 -0.9,-0.6 -1.4,-0.8L26.0,16.3c0.0,-0.2 -0.2,-0.3 -0.4,-0.3l-3.2,0.0c-0.2,0.0 -0.4,0.1 -0.4,0.3l-0.3,2.1c-0.5,0.2 -0.9,0.5 -1.4,0.8l-2.0,-0.8c-0.2,-0.1 -0.4,0.0 -0.5,0.2l-1.6,2.8c-0.1,0.2 -0.1,0.4 0.1,0.5l1.7,1.3c0.0,0.3 -0.1,0.5 -0.1,0.8s0.0,0.5 0.1,0.8l-1.7,1.3c-0.2,0.1 -0.2,0.3 -0.1,0.5l1.6,2.8c0.1,0.2 0.3,0.2 0.5,0.2l2.0,-0.8c0.4,0.3 0.9,0.6 1.4,0.8l0.3,2.1c0.0,0.2 0.2,0.3 0.4,0.3l3.2,0.0c0.2,0.0 0.4,-0.1 0.4,-0.3l0.3,-2.1c0.5,-0.2 0.9,-0.5 1.4,-0.8l2.0,0.8c0.2,0.1 0.4,0.0 0.5,-0.2l1.6,-2.8c0.1,-0.2 0.1,-0.4 -0.1,-0.5L29.9,24.8zM24.0,26.8c-1.5,0.0 -2.8,-1.3 -2.8,-2.8s1.3,-2.8 2.8,-2.8s2.8,1.3 2.8,2.8S25.5,26.8 24.0,26.8z"/>
- <path
- android:fillColor="#FF000000"
- android:pathData="M18.0,38.0c-0.6,0.0 -1.0,-0.4 -1.0,-1.0s0.4,-1.0 1.0,-1.0s1.0,0.4 1.0,1.0S18.6,38.0 18.0,38.0zM24.0,38.0c-0.6,0.0 -1.0,-0.4 -1.0,-1.0s0.4,-1.0 1.0,-1.0s1.0,0.4 1.0,1.0S24.6,38.0 24.0,38.0zM30.0,38.0c-0.6,0.0 -1.0,-0.4 -1.0,-1.0s0.4,-1.0 1.0,-1.0s1.0,0.4 1.0,1.0S30.6,38.0 30.0,38.0zM42.0,6.0L6.0,6.0c-2.2,0.0 -4.0,1.8 -4.0,4.0l0.0,28.0c0.0,2.2 1.8,4.0 4.0,4.0l36.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L46.0,10.0C46.0,7.8 44.2,6.0 42.0,6.0zM42.0,34.0L6.0,34.0L6.0,14.0l36.0,0.0L42.0,34.0zM9.0,12.0L7.0,12.0l0.0,-2.0l2.0,0.0L9.0,12.0zM13.0,12.0l-2.0,0.0l0.0,-2.0l2.0,0.0L13.0,12.0zM17.0,12.0l-2.0,0.0l0.0,-2.0l2.0,0.0L17.0,12.0z"/>
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M22.7,19.0l-9.1,-9.1c0.9,-2.0 0.4,-5.0 -1.5,-6.9 -2.0,-2.0 -5.0,-2.4 -7.4,-1.3L9.0,6.0 6.0,9.0 1.6,4.7C0.4,7.0 0.9,10.1 2.9,12.1c1.9,1.9 4.6,2.4 6.9,1.5l9.1,9.1c0.4,0.4 1.0,0.4 1.4,0.0l2.3,-2.3c0.5,-0.4 0.5,-1.0 0.1,-1.4z"/>
</vector>
diff --git a/packages/SystemUI/res/layout/status_bar_expanded_header.xml b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
index 7262ed2..8c8a3dd 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
@@ -44,14 +44,31 @@
android:scaleType="centerInside"/>
</com.android.systemui.statusbar.phone.MultiUserSwitch>
- <com.android.keyguard.AlphaOptimizedImageButton android:id="@+id/settings_button"
- style="@android:style/Widget.Material.Button.Borderless"
- android:layout_toStartOf="@id/multi_user_switch"
+ <com.android.keyguard.AlphaOptimizedLinearLayout
+ android:id="@+id/settings_button_container"
android:layout_width="48dp"
android:layout_height="@dimen/status_bar_header_height"
- android:background="@drawable/ripple_drawable"
- android:src="@drawable/ic_settings"
- android:contentDescription="@string/accessibility_desc_settings" />
+ android:paddingStart="12dp"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:layout_toStartOf="@id/multi_user_switch">
+
+ <com.android.systemui.statusbar.phone.SettingsButton android:id="@+id/settings_button"
+ style="@android:style/Widget.Material.Button.Borderless"
+ android:layout_width="24dp"
+ android:layout_height="@dimen/status_bar_header_height"
+ android:background="@drawable/ripple_drawable"
+ android:src="@drawable/ic_settings"
+ android:contentDescription="@string/accessibility_desc_settings" />
+ <com.android.systemui.statusbar.AlphaOptimizedImageView android:id="@+id/tuner_icon"
+ android:layout_width="12dp"
+ android:layout_height="@dimen/status_bar_header_height"
+ android:tint="#4DFFFFFF"
+ android:tintMode="src_in"
+ android:visibility="invisible"
+ android:src="@drawable/tuner" />
+
+ </com.android.keyguard.AlphaOptimizedLinearLayout>
<LinearLayout android:id="@+id/system_icons_super_container"
android:layout_width="wrap_content"
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index fcf7e3e..3eac84f 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1032,7 +1032,7 @@
<string name="volume_stream_vibrate_dnd" translatable="false">%s vibrate — Priority only</string>
<!-- Name of special SystemUI debug settings -->
- <string name="system_ui_tuner">System UI tuner</string>
+ <string name="system_ui_tuner">System UI Tuner</string>
<!-- Preference to show/hide embedded battery percentage [CHAR LIMIT=50] -->
<string name="show_battery_percentage">Show embedded battery percentage</string>
@@ -1099,4 +1099,25 @@
<!-- Accessibility label for managed profile icon (not shown on screen) [CHAR LIMIT=NONE] -->
<string name="accessibility_managed_profile">Work profile</string>
+ <!-- Title of warning when entering System UI tuner for first time [CHAR LIMIT=NONE] -->
+ <string name="tuner_warning_title">Fun for some but not for all</string>
+
+ <!-- Warning for users entering the System UI tuner for the first time [CHAR LIMIT=NONE]-->
+ <string name="tuner_warning">System UI Tuner gives you extra ways to tweak and customize the Android user interface. These experimental features may change, break, or disappear in future releases. Proceed with caution.</string>
+
+ <!-- Warning for users entering the System UI tuner [CHAR LIMIT=NONE]-->
+ <string name="tuner_persistent_warning">These experimental features may change, break, or disappear in future releases. Proceed with caution.</string>
+
+ <!-- Generic "got it" acceptance of dialog or cling [CHAR LIMIT=NONE] -->
+ <string name="got_it">Got it</string>
+
+ <!-- Toast describing tuner has been enabled [CHAR LIMIT=NONE] -->
+ <string name="tuner_toast">Congrats! System UI Tuner has been added to Settings</string>
+
+ <!-- Option to remove the tuner from settings [CHAR LIMIT=NONE] -->
+ <string name="remove_from_settings">Remove from Settings</string>
+
+ <!-- Dialog asking if the tuner should really be removed from settings [CHAR LIMIT=NONE]-->
+ <string name="remove_from_settings_prompt">Remove System UI Tuner from Settings and stop using all of its features?"</string>
+
</resources>
diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml
index 8c1acc3..3a41c3c 100644
--- a/packages/SystemUI/res/xml/tuner_prefs.xml
+++ b/packages/SystemUI/res/xml/tuner_prefs.xml
@@ -76,4 +76,8 @@
android:key="demo_mode"
android:title="@string/demo_mode" />
+ <Preference
+ android:summary="@string/tuner_persistent_warning"
+ android:selectable="false" />
+
</PreferenceScreen>
diff --git a/packages/SystemUI/src/com/android/systemui/DemoMode.java b/packages/SystemUI/src/com/android/systemui/DemoMode.java
index d406f5b..11996d0 100644
--- a/packages/SystemUI/src/com/android/systemui/DemoMode.java
+++ b/packages/SystemUI/src/com/android/systemui/DemoMode.java
@@ -20,6 +20,8 @@
public interface DemoMode {
+ public static final String DEMO_MODE_ALLOWED = "sysui_demo_allowed";
+
void dispatchDemoCommand(String command, Bundle args);
public static final String ACTION_DEMO = "com.android.systemui.demo";
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index f66a7dd..9265b63 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -304,4 +304,8 @@
public void onUserSwitched(int newUserId) {
updateAssistInfo();
}
+
+ public void onLockscreenShown() {
+ mAssistUtils.onLockscreenShown();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index 98558b4..9f21dbe 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -25,9 +25,9 @@
import android.os.Process;
import android.util.Log;
+import com.android.internal.policy.IKeyguardDrawnCallback;
import com.android.internal.policy.IKeyguardExitCallback;
import com.android.internal.policy.IKeyguardService;
-import com.android.internal.policy.IKeyguardShowCallback;
import com.android.internal.policy.IKeyguardStateCallback;
import com.android.systemui.SystemUIApplication;
@@ -120,9 +120,15 @@
}
@Override // Binder interface
- public void onStartedWakingUp(IKeyguardShowCallback callback) {
+ public void onStartedWakingUp() {
checkPermission();
- mKeyguardViewMediator.onStartedWakingUp(callback);
+ mKeyguardViewMediator.onStartedWakingUp();
+ }
+
+ @Override // Binder interface
+ public void onScreenTurningOn(IKeyguardDrawnCallback callback) {
+ checkPermission();
+ mKeyguardViewMediator.onScreenTurningOn(callback);
}
@Override // Binder interface
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 009a0d6..c01a485 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -41,6 +41,7 @@
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.SystemProperties;
+import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
@@ -55,8 +56,9 @@
import android.view.WindowManagerPolicy;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
+
+import com.android.internal.policy.IKeyguardDrawnCallback;
import com.android.internal.policy.IKeyguardExitCallback;
-import com.android.internal.policy.IKeyguardShowCallback;
import com.android.internal.policy.IKeyguardStateCallback;
import com.android.internal.telephony.IccCardConstants;
import com.android.internal.widget.LockPatternUtils;
@@ -77,7 +79,6 @@
import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
-
/**
* Mediates requests related to the keyguard. This includes queries about the
* state of the keyguard, power management events that effect whether the keyguard
@@ -138,7 +139,7 @@
private static final int RESET = 4;
private static final int VERIFY_UNLOCK = 5;
private static final int NOTIFY_SCREEN_OFF = 6;
- private static final int NOTIFY_SCREEN_ON = 7;
+ private static final int NOTIFY_SCREEN_TURNING_ON = 7;
private static final int KEYGUARD_DONE = 9;
private static final int KEYGUARD_DONE_DRAWING = 10;
private static final int KEYGUARD_DONE_AUTHENTICATING = 11;
@@ -148,6 +149,7 @@
private static final int START_KEYGUARD_EXIT_ANIM = 18;
private static final int ON_ACTIVITY_DRAWN = 19;
private static final int KEYGUARD_DONE_PENDING_TIMEOUT = 20;
+ private static final int NOTIFY_STARTED_WAKING_UP = 21;
/**
* The default amount of time we stay awake (used for all key input)
@@ -311,11 +313,14 @@
private boolean mPendingReset;
/**
- * When starting goign to sleep, we figured out that we need to lock Keyguard and this should be
+ * When starting going to sleep, we figured out that we need to lock Keyguard and this should be
* committed when finished going to sleep.
*/
private boolean mPendingLock;
+ private boolean mWakeAndUnlocking;
+ private IKeyguardDrawnCallback mDrawnCallback;
+
KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
@Override
@@ -454,12 +459,17 @@
}
@Override
- public void onFingerprintAuthenticated(int userId) {
+ public void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) {
if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
mStatusBarKeyguardViewManager.notifyKeyguardAuthenticated();
} else {
- mStatusBarKeyguardViewManager.animateCollapsePanels(
- FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR);
+ if (wakeAndUnlocking) {
+ mWakeAndUnlocking = true;
+ keyguardDone(true, true);
+ } else {
+ mStatusBarKeyguardViewManager.animateCollapsePanels(
+ FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR);
+ }
}
};
@@ -752,21 +762,23 @@
/**
* Let's us know when the device is waking up.
*/
- public void onStartedWakingUp(IKeyguardShowCallback callback) {
+ public void onStartedWakingUp() {
// TODO: Rename all screen off/on references to interactive/sleeping
synchronized (this) {
mDeviceInteractive = true;
cancelDoKeyguardLaterLocked();
if (DEBUG) Log.d(TAG, "onStartedWakingUp, seq = " + mDelayedShowingSequence);
- if (callback != null) {
- notifyScreenOnLocked(callback);
- }
+ notifyStartedWakingUp();
}
KeyguardUpdateMonitor.getInstance(mContext).dispatchScreenTurnedOn();
maybeSendUserPresentBroadcast();
}
+ public void onScreenTurningOn(IKeyguardDrawnCallback callback) {
+ notifyScreenOnLocked(callback);
+ }
+
private void maybeSendUserPresentBroadcast() {
if (mSystemReady && mLockPatternUtils.isLockScreenDisabled(
KeyguardUpdateMonitor.getCurrentUser())) {
@@ -1093,14 +1105,14 @@
mHandler.sendEmptyMessage(NOTIFY_SCREEN_OFF);
}
- /**
- * Send a message to keyguard telling it the screen just turned on.
- * @see #onScreenTurnedOn
- * @see #handleNotifyScreenOn
- */
- private void notifyScreenOnLocked(IKeyguardShowCallback result) {
+ private void notifyStartedWakingUp() {
+ if (DEBUG) Log.d(TAG, "notifyStartedWakingUp");
+ mHandler.sendEmptyMessage(NOTIFY_STARTED_WAKING_UP);
+ }
+
+ private void notifyScreenOnLocked(IKeyguardDrawnCallback callback) {
if (DEBUG) Log.d(TAG, "notifyScreenOnLocked");
- Message msg = mHandler.obtainMessage(NOTIFY_SCREEN_ON, result);
+ Message msg = mHandler.obtainMessage(NOTIFY_SCREEN_TURNING_ON, callback);
mHandler.sendMessage(msg);
}
@@ -1190,8 +1202,11 @@
case NOTIFY_SCREEN_OFF:
handleNotifyScreenOff();
break;
- case NOTIFY_SCREEN_ON:
- handleNotifyScreenOn((IKeyguardShowCallback) msg.obj);
+ case NOTIFY_SCREEN_TURNING_ON:
+ handleNotifyScreenTurningOn((IKeyguardDrawnCallback) msg.obj);
+ break;
+ case NOTIFY_STARTED_WAKING_UP:
+ handleNotifyStartedWakingUp();
break;
case KEYGUARD_DONE:
handleKeyguardDone(msg.arg1 != 0, msg.arg2 != 0);
@@ -1354,6 +1369,7 @@
setShowingLocked(true);
mStatusBarKeyguardViewManager.show(options);
mHiding = false;
+ mWakeAndUnlocking = false;
resetKeyguardDonePendingLocked();
mHideAnimationRun = false;
updateActivityLockScreenState();
@@ -1375,7 +1391,8 @@
// manager until it tells us it's safe to do so with
// startKeyguardExitAnimation.
ActivityManagerNative.getDefault().keyguardGoingAway(
- mStatusBarKeyguardViewManager.shouldDisableWindowAnimationsForUnlock(),
+ mStatusBarKeyguardViewManager.shouldDisableWindowAnimationsForUnlock()
+ || mWakeAndUnlocking,
mStatusBarKeyguardViewManager.isGoingToNotificationShade());
} catch (RemoteException e) {
Log.e(TAG, "Error while calling WindowManager", e);
@@ -1437,6 +1454,9 @@
updateActivityLockScreenState();
adjustStatusBarLocked();
sendUserPresentBroadcast();
+ if (mWakeAndUnlocking && mDrawnCallback != null) {
+ notifyDrawn(mDrawnCallback);
+ }
}
}
@@ -1508,14 +1528,31 @@
}
}
- /**
- * Handle message sent by {@link #notifyScreenOnLocked}
- * @see #NOTIFY_SCREEN_ON
- */
- private void handleNotifyScreenOn(IKeyguardShowCallback callback) {
+ private void handleNotifyStartedWakingUp() {
synchronized (KeyguardViewMediator.this) {
- if (DEBUG) Log.d(TAG, "handleNotifyScreenOn");
- mStatusBarKeyguardViewManager.onScreenTurnedOn(callback);
+ if (DEBUG) Log.d(TAG, "handleNotifyWakingUp");
+ mStatusBarKeyguardViewManager.onScreenTurnedOn();
+ }
+ }
+
+ private void handleNotifyScreenTurningOn(IKeyguardDrawnCallback callback) {
+ synchronized (KeyguardViewMediator.this) {
+ if (DEBUG) Log.d(TAG, "handleNotifyScreenTurningOn");
+ if (callback != null) {
+ if (mWakeAndUnlocking) {
+ mDrawnCallback = callback;
+ } else {
+ notifyDrawn(callback);
+ }
+ }
+ }
+ }
+
+ private void notifyDrawn(final IKeyguardDrawnCallback callback) {
+ try {
+ callback.onDrawn();
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Exception calling onDrawn():", e);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 07406b9..f3ad9d8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -45,6 +45,8 @@
private final MobileDataController mDataController;
private final CellularDetailAdapter mDetailAdapter;
+ private final CellSignalCallback mSignalCallback = new CellSignalCallback();
+
public CellularTile(Host host) {
super(host);
mController = host.getNetworkController();
@@ -90,8 +92,10 @@
protected void handleUpdateState(SignalState state, Object arg) {
state.visible = mController.hasMobileDataFeature();
if (!state.visible) return;
- final CallbackInfo cb = (CallbackInfo) arg;
- if (cb == null) return;
+ CallbackInfo cb = (CallbackInfo) arg;
+ if (cb == null) {
+ cb = mSignalCallback.mInfo;
+ }
final Resources r = mContext.getResources();
final int iconId = cb.noSim ? R.drawable.ic_qs_no_sim
@@ -152,7 +156,7 @@
boolean isDataTypeIconWide;
}
- private final SignalCallback mSignalCallback = new SignalCallbackAdapter() {
+ private final class CellSignalCallback extends SignalCallbackAdapter {
private final CallbackInfo mInfo = new CallbackInfo();
@Override
public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
index f7f7acb..3d0dc7b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
@@ -45,6 +45,8 @@
private int mCurrentUserId;
private String mIntentPackage;
+ private Intent mLastIntent;
+
private IntentTile(Host host, String action) {
super(host);
mContext.registerReceiver(mReceiver, new IntentFilter(action));
@@ -112,8 +114,16 @@
@Override
protected void handleUpdateState(State state, Object arg) {
- if (!(arg instanceof Intent)) return;
- final Intent intent = (Intent) arg;
+ Intent intent = (Intent) arg;
+ if (intent == null) {
+ if (mLastIntent == null) {
+ return;
+ }
+ // No intent but need to refresh state, just use the last one.
+ intent = mLastIntent;
+ }
+ // Save the last one in case we need it later.
+ mLastIntent = intent;
state.visible = intent.getBooleanExtra("visible", true);
state.contentDescription = intent.getStringExtra("contentDescription");
state.label = intent.getStringExtra("label");
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 3bfff2f..e654efd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -35,7 +35,6 @@
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.NetworkController.AccessPointController;
import com.android.systemui.statusbar.policy.NetworkController.IconState;
-import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
import com.android.systemui.statusbar.policy.SignalCallbackAdapter;
import java.util.List;
@@ -49,6 +48,8 @@
private final WifiDetailAdapter mDetailAdapter;
private final QSTile.SignalState mStateBeforeClick = newTileState();
+ private final WifiSignalCallback mSignalCallback = new WifiSignalCallback();
+
public WifiTile(Host host) {
super(host);
mController = host.getNetworkController();
@@ -118,8 +119,10 @@
protected void handleUpdateState(SignalState state, Object arg) {
state.visible = true;
if (DEBUG) Log.d(TAG, "handleUpdateState arg=" + arg);
- if (arg == null) return;
CallbackInfo cb = (CallbackInfo) arg;
+ if (cb == null) {
+ cb = mSignalCallback.mInfo;
+ }
boolean wifiConnected = cb.enabled && (cb.wifiSignalIconId > 0) && (cb.enabledDesc != null);
boolean wifiNotConnected = (cb.wifiSignalIconId > 0) && (cb.enabledDesc == null);
@@ -213,20 +216,21 @@
}
}
- private final SignalCallback mSignalCallback = new SignalCallbackAdapter() {
+ private final class WifiSignalCallback extends SignalCallbackAdapter {
+ final CallbackInfo mInfo = new CallbackInfo();
+
@Override
public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,
boolean activityIn, boolean activityOut, String description) {
if (DEBUG) Log.d(TAG, "onWifiSignalChanged enabled=" + enabled);
- final CallbackInfo info = new CallbackInfo();
- info.enabled = enabled;
- info.connected = qsIcon.visible;
- info.wifiSignalIconId = qsIcon.icon;
- info.enabledDesc = description;
- info.activityIn = activityIn;
- info.activityOut = activityOut;
- info.wifiSignalContentDescription = qsIcon.contentDescription;
- refreshState(info);
+ mInfo.enabled = enabled;
+ mInfo.connected = qsIcon.visible;
+ mInfo.wifiSignalIconId = qsIcon.icon;
+ mInfo.enabledDesc = description;
+ mInfo.activityIn = activityIn;
+ mInfo.activityOut = activityOut;
+ mInfo.wifiSignalContentDescription = qsIcon.contentDescription;
+ refreshState(mInfo);
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index f62dc59..a2e6632 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -729,11 +729,15 @@
}
protected void setNotificationShown(StatusBarNotification n) {
- mNotificationListener.setNotificationsShown(new String[] { n.getKey() });
+ setNotificationsShown(new String[]{n.getKey()});
}
protected void setNotificationsShown(String[] keys) {
- mNotificationListener.setNotificationsShown(keys);
+ try {
+ mNotificationListener.setNotificationsShown(keys);
+ } catch (RuntimeException e) {
+ Log.d(TAG, "failed setNotificationsShown: ", e);
+ }
}
protected boolean isCurrentProfile(int userId) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 91adc460..a5310a5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -641,7 +641,7 @@
}
@Override
- public void onFingerprintAuthenticated(int userId) {
+ public void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) {
}
@Override
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 2248905..42e35a9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1730,7 +1730,7 @@
}
private int adjustDisableFlags(int state) {
- if (!mLaunchTransitionFadingAway
+ if (!mLaunchTransitionFadingAway && !mKeyguardFadingAway
&& (mExpandedVisible || mBouncerShowing || mWaitingForKeyguardExit)) {
state |= StatusBarManager.DISABLE_NOTIFICATION_ICONS;
state |= StatusBarManager.DISABLE_SYSTEM_INFO;
@@ -2913,7 +2913,7 @@
updateRowStates();
mIconController.updateResources();
mScreenPinningRequest.onConfigurationChanged();
- mNetworkController.handleConfigurationChanged();
+ mNetworkController.onConfigurationChanged();
}
@Override
@@ -3211,7 +3211,7 @@
public void dispatchDemoCommand(String command, Bundle args) {
if (!mDemoModeAllowed) {
mDemoModeAllowed = Settings.Global.getInt(mContext.getContentResolver(),
- "sysui_demo_allowed", 0) != 0;
+ DEMO_MODE_ALLOWED, 0) != 0;
}
if (!mDemoModeAllowed) return;
if (command.equals(COMMAND_ENTER)) {
@@ -3311,6 +3311,7 @@
mDraggedDownRow.notifyHeightChanged(false /* needsAnimation */);
mDraggedDownRow = null;
}
+ mAssistManager.onLockscreenShown();
}
private void onLaunchTransitionFadingEnded() {
@@ -3460,7 +3461,7 @@
startTime + fadeoutDuration
- StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION,
StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION);
- disable(mDisabledUnmodified1, mDisabledUnmodified2, true /* animate */);
+ disable(mDisabledUnmodified1, mDisabledUnmodified2, fadeoutDuration > 0 /* animate */);
}
public boolean isKeyguardFadingAway() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java
new file mode 100644
index 0000000..a1e9ece
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2015 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.
+ * 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.systemui.statusbar.phone;
+
+import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.os.Handler;
+import android.os.Message;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+
+import com.android.keyguard.AlphaOptimizedImageButton;
+
+public class SettingsButton extends AlphaOptimizedImageButton {
+
+ private static final long LONG_PRESS_LENGTH = 1000;
+ private static final long ACCEL_LENGTH = 750;
+ private static final long FULL_SPEED_LENGTH = 375;
+ private static final long RUN_DURATION = 350;
+
+ private boolean mUpToSpeed;
+ private ObjectAnimator mAnimator;
+
+ private float mSlop;
+
+ public SettingsButton(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
+ }
+
+ public boolean isAnimating() {
+ return mAnimator != null && mAnimator.isRunning();
+ }
+
+ public boolean isTunerClick() {
+ return mUpToSpeed;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ switch (event.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN:
+ postDelayed(mLongPressCallback, LONG_PRESS_LENGTH);
+ break;
+ case MotionEvent.ACTION_UP:
+ if (mUpToSpeed) {
+ startExitAnimation();
+ } else {
+ cancelLongClick();
+ }
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ cancelLongClick();
+ break;
+ case MotionEvent.ACTION_MOVE:
+ float x = event.getX();
+ float y = event.getY();
+ if ((x < -mSlop) || (y < -mSlop) || (x > getWidth() + mSlop)
+ || (y > getHeight() + mSlop)) {
+ cancelLongClick();
+ }
+ break;
+ }
+ return super.onTouchEvent(event);
+ }
+
+ private void cancelLongClick() {
+ cancelAnimation();
+ mUpToSpeed = false;
+ removeCallbacks(mLongPressCallback);
+ }
+
+ private void cancelAnimation() {
+ if (mAnimator != null) {
+ mAnimator.removeAllListeners();
+ mAnimator.cancel();
+ mAnimator = null;
+ }
+ }
+
+ private void startExitAnimation() {
+ animate()
+ .translationX(((View) getParent().getParent()).getWidth() - getX())
+ .alpha(0)
+ .setDuration(RUN_DURATION)
+ .setInterpolator(AnimationUtils.loadInterpolator(mContext,
+ android.R.interpolator.accelerate_cubic))
+ .setListener(new AnimatorListener() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ setAlpha(1f);
+ setTranslationX(0);
+ cancelLongClick();
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ }
+ })
+ .start();
+ }
+
+ protected void startAccelSpin() {
+ cancelAnimation();
+ mAnimator = ObjectAnimator.ofFloat(this, View.ROTATION, 0, 360);
+ mAnimator.setInterpolator(AnimationUtils.loadInterpolator(mContext,
+ android.R.interpolator.accelerate_quad));
+ mAnimator.setDuration(ACCEL_LENGTH);
+ mAnimator.addListener(new AnimatorListener() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ startContinuousSpin();
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ }
+ });
+ mAnimator.start();
+ }
+
+ protected void startContinuousSpin() {
+ cancelAnimation();
+ mUpToSpeed = true;
+ mAnimator = ObjectAnimator.ofFloat(this, View.ROTATION, 0, 360);
+ mAnimator.setInterpolator(AnimationUtils.loadInterpolator(mContext,
+ android.R.interpolator.linear));
+ mAnimator.setDuration(FULL_SPEED_LENGTH);
+ mAnimator.setRepeatCount(Animation.INFINITE);
+ mAnimator.start();
+ }
+
+ private final Runnable mLongPressCallback = new Runnable() {
+ @Override
+ public void run() {
+ startAccelSpin();
+ }
+ };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
index a81f06e2..5d58cd0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
@@ -37,6 +37,7 @@
import android.widget.RelativeLayout;
import android.widget.Switch;
import android.widget.TextView;
+import android.widget.Toast;
import com.android.keyguard.KeyguardStatusView;
import com.android.systemui.BatteryMeterView;
@@ -48,6 +49,7 @@
import com.android.systemui.statusbar.policy.NetworkControllerImpl.EmergencyListener;
import com.android.systemui.statusbar.policy.NextAlarmController;
import com.android.systemui.statusbar.policy.UserInfoController;
+import com.android.systemui.tuner.TunerService;
import java.text.NumberFormat;
@@ -73,7 +75,8 @@
private TextView mDateExpanded;
private LinearLayout mSystemIcons;
private View mSignalCluster;
- private View mSettingsButton;
+ private SettingsButton mSettingsButton;
+ private View mSettingsContainer;
private View mQsDetailHeader;
private TextView mQsDetailHeaderTitle;
private Switch mQsDetailHeaderSwitch;
@@ -142,7 +145,8 @@
mMultiUserAvatar = (ImageView) findViewById(R.id.multi_user_avatar);
mDateCollapsed = (TextView) findViewById(R.id.date_collapsed);
mDateExpanded = (TextView) findViewById(R.id.date_expanded);
- mSettingsButton = findViewById(R.id.settings_button);
+ mSettingsButton = (SettingsButton) findViewById(R.id.settings_button);
+ mSettingsContainer = findViewById(R.id.settings_button_container);
mSettingsButton.setOnClickListener(this);
mQsDetailHeader = findViewById(R.id.qs_detail_header);
mQsDetailHeader.setAlpha(0);
@@ -323,13 +327,15 @@
mDateCollapsed.setVisibility(mExpanded && mAlarmShowing ? View.VISIBLE : View.INVISIBLE);
mDateExpanded.setVisibility(mExpanded && mAlarmShowing ? View.INVISIBLE : View.VISIBLE);
mAlarmStatus.setVisibility(mExpanded && mAlarmShowing ? View.VISIBLE : View.INVISIBLE);
- mSettingsButton.setVisibility(mExpanded ? View.VISIBLE : View.INVISIBLE);
+ mSettingsContainer.setVisibility(mExpanded ? View.VISIBLE : View.INVISIBLE);
mQsDetailHeader.setVisibility(mExpanded && mShowingDetail? View.VISIBLE : View.INVISIBLE);
if (mSignalCluster != null) {
updateSignalClusterDetachment();
}
mEmergencyCallsOnly.setVisibility(mExpanded && mShowEmergencyCallsOnly ? VISIBLE : GONE);
mBatteryLevel.setVisibility(mExpanded ? View.VISIBLE : View.GONE);
+ mSettingsContainer.findViewById(R.id.tuner_icon).setVisibility(
+ TunerService.isTunerEnabled(mContext) ? View.VISIBLE : View.INVISIBLE);
}
private void updateSignalClusterDetachment() {
@@ -352,7 +358,7 @@
private void updateSystemIconsLayoutParams() {
RelativeLayout.LayoutParams lp = (LayoutParams) mSystemIconsSuperContainer.getLayoutParams();
int rule = mExpanded
- ? mSettingsButton.getId()
+ ? mSettingsContainer.getId()
: mMultiUserSwitch.getId();
if (rule != lp.getRules()[RelativeLayout.START_OF]) {
lp.addRule(RelativeLayout.START_OF, rule);
@@ -495,6 +501,20 @@
@Override
public void onClick(View v) {
if (v == mSettingsButton) {
+ if (mSettingsButton.isTunerClick()) {
+ if (TunerService.isTunerEnabled(mContext)) {
+ TunerService.showResetRequest(mContext, new Runnable() {
+ @Override
+ public void run() {
+ // Relaunch settings so that the tuner disappears.
+ startSettingsActivity();
+ }
+ });
+ } else {
+ Toast.makeText(getContext(), R.string.tuner_toast, Toast.LENGTH_LONG).show();
+ TunerService.setTunerEnabled(mContext, true);
+ }
+ }
startSettingsActivity();
} else if (v == mSystemIconsSuperContainer) {
startBatteryActivity();
@@ -567,10 +587,10 @@
}
target.batteryY = mSystemIconsSuperContainer.getTop() + mSystemIconsContainer.getTop();
target.batteryLevelAlpha = getAlphaForVisibility(mBatteryLevel);
- target.settingsAlpha = getAlphaForVisibility(mSettingsButton);
+ target.settingsAlpha = getAlphaForVisibility(mSettingsContainer);
target.settingsTranslation = mExpanded
? 0
- : mMultiUserSwitch.getLeft() - mSettingsButton.getLeft();
+ : mMultiUserSwitch.getLeft() - mSettingsContainer.getLeft();
target.signalClusterAlpha = mSignalClusterDetached ? 0f : 1f;
target.settingsRotation = !mExpanded ? 90f : 0f;
}
@@ -622,9 +642,11 @@
mSignalCluster.setTranslationX(0f);
mSignalCluster.setTranslationY(0f);
}
- mSettingsButton.setTranslationY(mSystemIconsSuperContainer.getTranslationY());
- mSettingsButton.setTranslationX(values.settingsTranslation);
- mSettingsButton.setRotation(values.settingsRotation);
+ if (!mSettingsButton.isAnimating()) {
+ mSettingsContainer.setTranslationY(mSystemIconsSuperContainer.getTranslationY());
+ mSettingsContainer.setTranslationX(values.settingsTranslation);
+ mSettingsButton.setRotation(values.settingsRotation);
+ }
applyAlpha(mEmergencyCallsOnly, values.emergencyCallsOnlyAlpha);
if (!mShowingDetail && !mDetailTransitioning) {
// Otherwise it needs to stay invisible
@@ -633,7 +655,7 @@
applyAlpha(mDateCollapsed, values.dateCollapsedAlpha);
applyAlpha(mDateExpanded, values.dateExpandedAlpha);
applyAlpha(mBatteryLevel, values.batteryLevelAlpha);
- applyAlpha(mSettingsButton, values.settingsAlpha);
+ applyAlpha(mSettingsContainer, values.settingsAlpha);
applyAlpha(mSignalCluster, values.signalClusterAlpha);
if (!mExpanded) {
mTime.setScaleX(1f);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index a69416a..e622144 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -19,15 +19,12 @@
import android.content.ComponentCallbacks2;
import android.content.Context;
import android.os.Bundle;
-import android.os.RemoteException;
import android.os.SystemClock;
-import android.util.Slog;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManagerGlobal;
-import com.android.internal.policy.IKeyguardShowCallback;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.ViewMediatorCallback;
@@ -163,26 +160,10 @@
mBouncer.onScreenTurnedOff();
}
- public void onScreenTurnedOn(final IKeyguardShowCallback callback) {
+ public void onScreenTurnedOn() {
mScreenOn = true;
mScreenWillWakeUp = false;
mPhoneStatusBar.onScreenTurnedOn();
- if (callback != null) {
- callbackAfterDraw(callback);
- }
- }
-
- private void callbackAfterDraw(final IKeyguardShowCallback callback) {
- mContainer.post(new Runnable() {
- @Override
- public void run() {
- try {
- callback.onShown(mContainer.getWindowToken());
- } catch (RemoteException e) {
- Slog.w(TAG, "Exception calling onShown():", e);
- }
- }
- });
}
public void notifyScreenWakeUpRequested() {
@@ -270,16 +251,22 @@
mPhoneStatusBar.setKeyguardFadingAway(startTime, delay, fadeoutDuration);
boolean staying = mPhoneStatusBar.hideKeyguard();
if (!staying) {
- mStatusBarWindowManager.setKeyguardFadingAway(true);
- mScrimController.animateKeyguardFadingOut(delay, fadeoutDuration, new Runnable() {
- @Override
- public void run() {
- mStatusBarWindowManager.setKeyguardFadingAway(false);
- mPhoneStatusBar.finishKeyguardFadingAway();
- WindowManagerGlobal.getInstance().trimMemory(
- ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
- }
- });
+ if (fadeoutDuration == 0) {
+ mPhoneStatusBar.finishKeyguardFadingAway();
+ WindowManagerGlobal.getInstance().trimMemory(
+ ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
+ } else {
+ mStatusBarWindowManager.setKeyguardFadingAway(true);
+ mScrimController.animateKeyguardFadingOut(delay, fadeoutDuration, new Runnable() {
+ @Override
+ public void run() {
+ mStatusBarWindowManager.setKeyguardFadingAway(false);
+ mPhoneStatusBar.finishKeyguardFadingAway();
+ WindowManagerGlobal.getInstance().trimMemory(
+ ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
+ }
+ });
+ }
} else {
mScrimController.animateGoingToFullShade(delay, fadeoutDuration);
mPhoneStatusBar.finishKeyguardFadingAway();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
index 6fc15a8..f31311d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
@@ -132,7 +132,7 @@
}
@Override
- public void onFingerprintAuthenticated(int userId) {
+ public void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) {
update(false /* updateAlways */);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 81f2d532..7cd94d7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -197,7 +197,6 @@
filter.addAction(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION);
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
filter.addAction(ConnectivityManager.INET_CONDITION_ACTION);
- filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
mContext.registerReceiver(this, filter, null, mReceiverHandler);
mListening = true;
@@ -339,8 +338,6 @@
if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION) ||
action.equals(ConnectivityManager.INET_CONDITION_ACTION)) {
updateConnectivity();
- } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
- handleConfigurationChanged();
} else if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
refreshLocale();
updateAirplaneMode(false);
@@ -373,8 +370,18 @@
}
}
- public void handleConfigurationChanged() {
+ public void onConfigurationChanged() {
mConfig = Config.readConfig(mContext);
+ mReceiverHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ handleConfigurationChanged();
+ }
+ });
+ }
+
+ @VisibleForTesting
+ void handleConfigurationChanged() {
for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
mobileSignalController.setConfiguration(mConfig);
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
index 3f5ca58..a2b062c 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
@@ -28,13 +28,14 @@
import android.preference.PreferenceScreen;
import android.preference.SwitchPreference;
import android.provider.Settings;
+import android.view.MenuItem;
+import com.android.internal.logging.MetricsLogger;
import com.android.systemui.DemoMode;
import com.android.systemui.R;
public class DemoModeFragment extends PreferenceFragment implements OnPreferenceChangeListener {
- private static final String DEMO_MODE_ALLOWED = "sysui_demo_allowed";
private static final String DEMO_MODE_ON = "sysui_tuner_demo_on";
private static final String[] STATUS_ICONS = {
@@ -75,10 +76,33 @@
updateDemoModeEnabled();
updateDemoModeOn();
ContentResolver contentResolver = getContext().getContentResolver();
- contentResolver.registerContentObserver(Settings.Global.getUriFor(DEMO_MODE_ALLOWED), false,
- mDemoModeObserver);
+ contentResolver.registerContentObserver(Settings.Global.getUriFor(
+ DemoMode.DEMO_MODE_ALLOWED), false, mDemoModeObserver);
contentResolver.registerContentObserver(Settings.Global.getUriFor(DEMO_MODE_ON), false,
mDemoModeObserver);
+ setHasOptionsMenu(true);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ getFragmentManager().popBackStack();
+ break;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ MetricsLogger.visibility(getContext(), MetricsLogger.TUNER_DEMO_MODE, true);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ MetricsLogger.visibility(getContext(), MetricsLogger.TUNER_DEMO_MODE, false);
}
@Override
@@ -89,7 +113,7 @@
private void updateDemoModeEnabled() {
boolean enabled = Settings.Global.getInt(getContext().getContentResolver(),
- DEMO_MODE_ALLOWED, 0) != 0;
+ DemoMode.DEMO_MODE_ALLOWED, 0) != 0;
mEnabledSwitch.setChecked(enabled);
mOnSwitch.setEnabled(enabled);
}
@@ -102,15 +126,18 @@
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
+ boolean enabled = newValue == Boolean.TRUE;
if (preference == mEnabledSwitch) {
- if (newValue != Boolean.TRUE) {
+ if (!enabled) {
// Make sure we aren't in demo mode when disabling it.
mOnSwitch.setChecked(false);
stopDemoMode();
}
- setGlobal(DEMO_MODE_ALLOWED, newValue == Boolean.TRUE ? 1 : 0);
+ MetricsLogger.action(getContext(), MetricsLogger.TUNER_DEMO_MODE_ENABLED, enabled);
+ setGlobal(DemoMode.DEMO_MODE_ALLOWED, enabled ? 1 : 0);
} else if (preference == mOnSwitch) {
- if (newValue == Boolean.TRUE) {
+ MetricsLogger.action(getContext(), MetricsLogger.TUNER_DEMO_MODE_ON, enabled);
+ if (enabled) {
startDemoMode();
} else {
stopDemoMode();
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java b/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java
index a5b244e..37ac098 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java
@@ -40,6 +40,7 @@
import android.widget.FrameLayout;
import android.widget.ScrollView;
+import com.android.internal.logging.MetricsLogger;
import com.android.systemui.R;
import com.android.systemui.qs.QSPanel;
import com.android.systemui.qs.QSTile;
@@ -79,12 +80,25 @@
menu.add(0, MENU_RESET, 0, com.android.internal.R.string.reset);
}
+ public void onResume() {
+ super.onResume();
+ MetricsLogger.visibility(getContext(), MetricsLogger.TUNER_QS, true);
+ }
+
+ public void onPause() {
+ super.onPause();
+ MetricsLogger.visibility(getContext(), MetricsLogger.TUNER_QS, false);
+ }
+
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_RESET:
mTileHost.reset();
break;
+ case android.R.id.home:
+ getFragmentManager().popBackStack();
+ break;
}
return super.onOptionsItemSelected(item);
}
@@ -205,6 +219,8 @@
if (oldTile.equals(newTile)) {
return;
}
+ MetricsLogger.action(getContext(), MetricsLogger.TUNER_QS_REORDER, oldTile + ","
+ + newTile);
List<String> order = new ArrayList<>(mTileSpecs);
int index = order.indexOf(oldTile);
if (index < 0) {
@@ -217,12 +233,14 @@
}
public void remove(String tile) {
+ MetricsLogger.action(getContext(), MetricsLogger.TUNER_QS_REMOVE, tile);
List<String> tiles = new ArrayList<>(mTileSpecs);
tiles.remove(tile);
setTiles(tiles);
}
public void add(String tile) {
+ MetricsLogger.action(getContext(), MetricsLogger.TUNER_QS_ADD, tile);
List<String> tiles = new ArrayList<>(mTileSpecs);
tiles.add(tile);
setTiles(tiles);
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java
index d4cc56d..e5b550e 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java
@@ -23,6 +23,7 @@
import android.text.TextUtils;
import android.util.AttributeSet;
+import com.android.internal.logging.MetricsLogger;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.tuner.TunerService.Tunable;
@@ -50,11 +51,14 @@
if (!value) {
// If not enabled add to blacklist.
if (!mBlacklist.contains(getKey())) {
+ MetricsLogger.action(getContext(), MetricsLogger.TUNER_STATUS_BAR_DISABLE,
+ getKey());
mBlacklist.add(getKey());
setList(mBlacklist);
}
} else {
if (mBlacklist.remove(getKey())) {
+ MetricsLogger.action(getContext(), MetricsLogger.TUNER_STATUS_BAR_ENABLE, getKey());
setList(mBlacklist);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
index 4a8c2e4..71b5de5 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
@@ -17,7 +17,10 @@
import static com.android.systemui.BatteryMeterView.SHOW_PERCENT_SETTING;
+import android.app.AlertDialog;
import android.app.FragmentTransaction;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Bundle;
@@ -28,19 +31,29 @@
import android.preference.PreferenceFragment;
import android.preference.PreferenceGroup;
import android.preference.SwitchPreference;
+import android.provider.Settings;
import android.provider.Settings.System;
+import android.view.Menu;
+import android.view.MenuInflater;
import android.view.MenuItem;
+import com.android.internal.logging.MetricsLogger;
import com.android.systemui.R;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.tuner.TunerService.Tunable;
public class TunerFragment extends PreferenceFragment {
+ private static final String TAG = "TunerFragment";
+
private static final String KEY_QS_TUNER = "qs_tuner";
private static final String KEY_DEMO_MODE = "demo_mode";
private static final String KEY_BATTERY_PCT = "battery_pct";
+ public static final String SETTING_SEEN_TUNER_WARNING = "seen_tuner_warning";
+
+ private static final int MENU_REMOVE = Menu.FIRST + 1;
+
private final SettingObserver mSettingObserver = new SettingObserver();
private SwitchPreference mBatteryPct;
@@ -73,6 +86,19 @@
}
});
mBatteryPct = (SwitchPreference) findPreference(KEY_BATTERY_PCT);
+ if (Settings.Secure.getInt(getContext().getContentResolver(), SETTING_SEEN_TUNER_WARNING,
+ 0) == 0) {
+ new AlertDialog.Builder(getContext())
+ .setTitle(R.string.tuner_warning_title)
+ .setMessage(R.string.tuner_warning)
+ .setPositiveButton(R.string.got_it, new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Settings.Secure.putInt(getContext().getContentResolver(),
+ SETTING_SEEN_TUNER_WARNING, 1);
+ }
+ }).show();
+ }
}
@Override
@@ -83,6 +109,7 @@
System.getUriFor(SHOW_PERCENT_SETTING), false, mSettingObserver);
registerPrefs(getPreferenceScreen());
+ MetricsLogger.visibility(getContext(), MetricsLogger.TUNER, true);
}
@Override
@@ -91,6 +118,7 @@
getContext().getContentResolver().unregisterContentObserver(mSettingObserver);
unregisterPrefs(getPreferenceScreen());
+ MetricsLogger.visibility(getContext(), MetricsLogger.TUNER, false);
}
private void registerPrefs(PreferenceGroup group) {
@@ -120,11 +148,24 @@
}
@Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ menu.add(Menu.NONE, MENU_REMOVE, Menu.NONE, R.string.remove_from_settings);
+ }
+
+ @Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
getActivity().finish();
return true;
+ case MENU_REMOVE:
+ TunerService.showResetRequest(getContext(), new Runnable() {
+ @Override
+ public void run() {
+ getActivity().finish();
+ }
+ });
+ return true;
}
return super.onOptionsItemSelected(item);
}
@@ -152,6 +193,7 @@
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
final boolean v = (Boolean) newValue;
+ MetricsLogger.action(getContext(), MetricsLogger.TUNER_BATTERY_PERCENTAGE, v);
System.putInt(getContext().getContentResolver(), SHOW_PERCENT_SETTING, v ? 1 : 0);
return true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
index de5aaf6..d3f33ab 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
@@ -16,8 +16,15 @@
package com.android.systemui.tuner;
import android.app.ActivityManager;
+import android.app.AlertDialog;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
@@ -25,9 +32,13 @@
import android.provider.Settings;
import android.util.ArrayMap;
+import com.android.systemui.BatteryMeterView;
+import com.android.systemui.DemoMode;
+import com.android.systemui.R;
import com.android.systemui.SystemUI;
import com.android.systemui.SystemUIApplication;
import com.android.systemui.settings.CurrentUserTracker;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
import java.util.ArrayList;
import java.util.HashMap;
@@ -36,6 +47,8 @@
public class TunerService extends SystemUI {
+ public static final String ACTION_CLEAR = "com.android.systemui.action.CLEAR_TUNER";
+
private final Observer mObserver = new Observer();
// Map of Uris we listen on to their settings keys.
private final ArrayMap<Uri, String> mListeningUris = new ArrayMap<>();
@@ -118,6 +131,19 @@
}
}
+ public void clearAll() {
+ // A couple special cases.
+ Settings.Global.putString(mContentResolver, DemoMode.DEMO_MODE_ALLOWED, null);
+ Settings.System.putString(mContentResolver, BatteryMeterView.SHOW_PERCENT_SETTING, null);
+ Intent intent = new Intent(DemoMode.ACTION_DEMO);
+ intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_EXIT);
+ mContext.sendBroadcast(intent);
+
+ for (String key : mTunableLookup.keySet()) {
+ Settings.Secure.putString(mContentResolver, key, null);
+ }
+ }
+
// Only used in other processes, such as the tuner.
private static TunerService sInstance;
@@ -141,6 +167,44 @@
return sInstance;
}
+ public static final void showResetRequest(final Context context, final Runnable onDisabled) {
+ SystemUIDialog dialog = new SystemUIDialog(context);
+ dialog.setMessage(R.string.remove_from_settings_prompt);
+ dialog.setButton(DialogInterface.BUTTON_NEGATIVE, context.getString(R.string.cancel),
+ (OnClickListener) null);
+ dialog.setButton(DialogInterface.BUTTON_POSITIVE,
+ context.getString(R.string.guest_exit_guest_dialog_remove), new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // Tell the tuner (in main SysUI process) to clear all its settings.
+ context.sendBroadcast(new Intent(TunerService.ACTION_CLEAR));
+ // Disable access to tuner.
+ TunerService.setTunerEnabled(context, false);
+ // Make them sit through the warning dialog again.
+ Settings.Secure.putInt(context.getContentResolver(),
+ TunerFragment.SETTING_SEEN_TUNER_WARNING, 0);
+ if (onDisabled != null) {
+ onDisabled.run();
+ }
+ }
+ });
+ dialog.show();
+ }
+
+ public static final void setTunerEnabled(Context context, boolean enabled) {
+ context.getPackageManager().setComponentEnabledSetting(
+ new ComponentName(context, TunerActivity.class),
+ enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
+ : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+ PackageManager.DONT_KILL_APP);
+ }
+
+ public static final boolean isTunerEnabled(Context context) {
+ return context.getPackageManager().getComponentEnabledSetting(
+ new ComponentName(context, TunerActivity.class))
+ == PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+ }
+
private class Observer extends ContentObserver {
public Observer() {
super(new Handler(Looper.getMainLooper()));
@@ -157,4 +221,13 @@
public interface Tunable {
void onTuningChanged(String key, String newValue);
}
+
+ public static class ClearReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (ACTION_CLEAR.equals(intent.getAction())) {
+ get(context).clearAll();
+ }
+ }
+ }
}
diff --git a/services/core/java/com/android/server/AssetAtlasService.java b/services/core/java/com/android/server/AssetAtlasService.java
index ebc810f..4569dae 100644
--- a/services/core/java/com/android/server/AssetAtlasService.java
+++ b/services/core/java/com/android/server/AssetAtlasService.java
@@ -93,7 +93,7 @@
// Defines the number of int fields used to represent a single entry
// in the atlas map. This number defines the size of the array returned
// by the getMap(). See the mAtlasMap field for more information
- private static final int ATLAS_MAP_ENTRY_FIELD_COUNT = 4;
+ private static final int ATLAS_MAP_ENTRY_FIELD_COUNT = 3;
// Specifies how our GraphicBuffer will be used. To get proper swizzling
// the buffer will be written to using OpenGL (from JNI) so we can leave
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index c7c9d29..7561c7d 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -253,6 +253,8 @@
"max_temp_app_whitelist_duration";
private static final String KEY_MMS_TEMP_APP_WHITELIST_DURATION =
"mms_temp_app_whitelist_duration";
+ private static final String KEY_SMS_TEMP_APP_WHITELIST_DURATION =
+ "sms_temp_app_whitelist_duration";
/**
* This is the time, after becoming inactive, at which we start looking at the
@@ -357,6 +359,13 @@
*/
public long MMS_TEMP_APP_WHITELIST_DURATION;
+ /**
+ * Amount of time we would like to whitelist an app that is receiving an SMS.
+ * @see Settings.Global#DEVICE_IDLE_CONSTANTS
+ * @see #KEY_SMS_TEMP_APP_WHITELIST_DURATION
+ */
+ public long SMS_TEMP_APP_WHITELIST_DURATION;
+
private final ContentResolver mResolver;
private final KeyValueListParser mParser = new KeyValueListParser(',');
@@ -410,6 +419,8 @@
KEY_MAX_TEMP_APP_WHITELIST_DURATION, 5 * 60 * 1000L);
MMS_TEMP_APP_WHITELIST_DURATION = mParser.getLong(
KEY_MMS_TEMP_APP_WHITELIST_DURATION, 60 * 1000L);
+ SMS_TEMP_APP_WHITELIST_DURATION = mParser.getLong(
+ KEY_SMS_TEMP_APP_WHITELIST_DURATION, 20 * 1000L);
}
}
@@ -465,6 +476,10 @@
pw.print(" "); pw.print(KEY_MMS_TEMP_APP_WHITELIST_DURATION); pw.print("=");
TimeUtils.formatDuration(MMS_TEMP_APP_WHITELIST_DURATION, pw);
pw.println();
+
+ pw.print(" "); pw.print(KEY_SMS_TEMP_APP_WHITELIST_DURATION); pw.print("=");
+ TimeUtils.formatDuration(SMS_TEMP_APP_WHITELIST_DURATION, pw);
+ pw.println();
}
}
@@ -617,6 +632,13 @@
return duration;
}
+ @Override public long addPowerSaveTempWhitelistAppForSms(String packageName,
+ int userId, String reason) throws RemoteException {
+ long duration = mConstants.SMS_TEMP_APP_WHITELIST_DURATION;
+ addPowerSaveTempWhitelistApp(packageName, duration, userId, reason);
+ return duration;
+ }
+
@Override public void exitIdle(String reason) {
getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
null);
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index e57e3ff..a75cc48 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -617,12 +617,9 @@
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
ActivityRecord r = activities.get(activityNdx);
if (notCurrentUserTask && (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) == 0) {
- return null;
+ continue;
}
if (!r.finishing && r.intent.getComponent().equals(cls) && r.userId == userId) {
- //Slog.i(TAG, "Found matching class!");
- //dump();
- //Slog.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
return r;
}
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index eef3d63..1223a00 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -5126,6 +5126,11 @@
if (UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID) {
continue;
}
+ // Skip packages that have permission to interact across users
+ if (pm.checkPermission(Manifest.permission.INTERACT_ACROSS_USERS, pkg.packageName)
+ == PackageManager.PERMISSION_GRANTED) {
+ continue;
+ }
if (homeActivityName != null
&& pkg.packageName.equals(homeActivityName.getPackageName())
&& pkg.applicationInfo.isSystemApp()) {
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 8871e64..c705fbf 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -74,7 +74,6 @@
private static final int MSG_USER_SWITCHING = 10;
private static final int ENROLLMENT_TIMEOUT_MS = 60 * 1000; // 1 minute
- private boolean mIsKeyguard; // true if the authentication client is keyguard
private ClientMonitor mAuthClient = null;
private ClientMonitor mEnrollClient = null;
private ClientMonitor mRemoveClient = null;
@@ -124,20 +123,29 @@
public void binderDied() {
Slog.v(TAG, "fingerprintd died");
mDaemon = null;
+ dispatchError(mHalDeviceId, FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE);
}
public IFingerprintDaemon getFingerprintDaemon() {
if (mDaemon == null) {
mDaemon = IFingerprintDaemon.Stub.asInterface(ServiceManager.getService(FINGERPRINTD));
- if (mDaemon == null) {
- Slog.w(TAG, "fingerprind service not available");
- } else {
+ if (mDaemon != null) {
try {
mDaemon.asBinder().linkToDeath(this, 0);
- } catch (RemoteException e) {
- Slog.w(TAG, "caught remote exception in linkToDeath: ", e);
- mDaemon = null; // try again!
+ mDaemon.init(mDaemonCallback);
+ mHalDeviceId = mDaemon.openHal();
+ if (mHalDeviceId != 0) {
+ updateActiveGroup(ActivityManager.getCurrentUser());
+ } else {
+ Slog.w(TAG, "Failed to open Fingerprint HAL!");
+ mDaemon = null;
+ }
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to open fingeprintd HAL", e);
+ mDaemon = null; // try again later!
}
+ } else {
+ Slog.w(TAG, "fingerprint service not available");
}
}
return mDaemon;
@@ -156,7 +164,6 @@
protected void dispatchRemoved(long deviceId, int fingerId, int groupId) {
final ClientMonitor client = mRemoveClient;
if (fingerId != 0) {
- ContentResolver res = mContext.getContentResolver();
removeTemplateForUser(mRemoveClient, fingerId);
}
if (client != null && client.sendRemoved(fingerId, groupId)) {
@@ -577,12 +584,6 @@
result |= true; // we have a valid fingerprint
mLockoutReset.run();
}
- // For fingerprint devices that support touch-to-wake, this will ensure the device
- // wakes up and turns the screen on when fingerprint is authenticated.
- if (mIsKeyguard && authenticated) {
- mPowerManager.wakeUp(SystemClock.uptimeMillis(),
- "android.server.fingerprint:AUTH");
- }
return result;
}
@@ -727,7 +728,6 @@
mHandler.post(new Runnable() {
@Override
public void run() {
- mIsKeyguard = KEYGUARD_PACKAGE.equals(opPackageName);
startAuthentication(token, opId, groupId, receiver, flags, restricted);
}
});
@@ -821,15 +821,6 @@
public void onStart() {
publishBinderService(Context.FINGERPRINT_SERVICE, new FingerprintServiceWrapper());
IFingerprintDaemon daemon = getFingerprintDaemon();
- if (daemon != null) {
- try {
- daemon.init(mDaemonCallback);
- mHalDeviceId = daemon.openHal();
- updateActiveGroup(ActivityManager.getCurrentUser());
- } catch (RemoteException e) {
- Slog.e(TAG, "Failed to open fingeprintd HAL", e);
- }
- }
if (DEBUG) Slog.v(TAG, "Fingerprint HAL id: " + mHalDeviceId);
listenForUserSwitches();
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 07de6f5..0366fff 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -91,7 +91,6 @@
import com.android.internal.util.ImageUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.IoThread;
-import com.google.android.collect.Sets;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -106,6 +105,7 @@
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Random;
@@ -221,7 +221,7 @@
reconcileStagesLocked(StorageManager.UUID_PRIVATE_INTERNAL);
- final ArraySet<File> unclaimedIcons = Sets.newArraySet(
+ final ArraySet<File> unclaimedIcons = newArraySet(
mSessionsDir.listFiles());
// Ignore stages and icons claimed by active sessions
@@ -245,7 +245,7 @@
private void reconcileStagesLocked(String volumeUuid) {
final File stagingDir = buildStagingDir(volumeUuid);
- final ArraySet<File> unclaimedStages = Sets.newArraySet(
+ final ArraySet<File> unclaimedStages = newArraySet(
stagingDir.listFiles(sStageFilter));
// Ignore stages claimed by active sessions
@@ -1091,6 +1091,15 @@
.build();
}
+ public static <E> ArraySet<E> newArraySet(E... elements) {
+ final ArraySet<E> set = new ArraySet<E>();
+ if (elements != null) {
+ set.ensureCapacity(elements.length);
+ Collections.addAll(set, elements);
+ }
+ return set;
+ }
+
private static class Callbacks extends Handler {
private static final int MSG_SESSION_CREATED = 1;
private static final int MSG_SESSION_BADGING_CHANGED = 2;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index c139389..0b74996 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -7321,6 +7321,9 @@
for (i=0; i<N; i++) {
PackageParser.Permission p = pkg.permissions.get(i);
+ // Assume by default that we did not install this permission into the system.
+ p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
+
// Now that permission groups have a special meaning, we ignore permission
// groups for legacy apps to prevent unexpected behavior. In particular,
// permissions for one app being granted to someone just becuase they happen
@@ -7350,6 +7353,7 @@
bp.perm = p;
bp.uid = pkg.applicationInfo.uid;
bp.sourcePackage = p.info.packageName;
+ p.info.flags |= PermissionInfo.FLAG_INSTALLED;
} else if (!currentOwnerIsSystem) {
String msg = "New decl " + p.owner + " of permission "
+ p.info.name + " is system; overriding " + bp.sourcePackage;
@@ -7375,6 +7379,7 @@
bp.perm = p;
bp.uid = pkg.applicationInfo.uid;
bp.sourcePackage = p.info.packageName;
+ p.info.flags |= PermissionInfo.FLAG_INSTALLED;
if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
if (r == null) {
r = new StringBuilder(256);
@@ -14688,12 +14693,12 @@
pw.println(" s[hared-users]: dump shared user IDs");
pw.println(" m[essages]: print collected runtime messages");
pw.println(" v[erifiers]: print package verifier info");
- pw.println(" version: print database version info");
- pw.println(" write: write current settings now");
- pw.println(" <package.name>: info about given package");
- pw.println(" installs: details about install sessions");
pw.println(" d[omain-preferred-apps]: print domains preferred apps");
pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
+ pw.println(" version: print database version info");
+ pw.println(" write: write current settings now");
+ pw.println(" installs: details about install sessions");
+ pw.println(" <package.name>: info about given package");
return;
} else if ("--checkin".equals(opt)) {
checkin = true;
@@ -15600,12 +15605,8 @@
* recycled.
*/
private void reconcileUsers(String volumeUuid) {
- final File[] files = Environment.getDataUserDirectory(volumeUuid).listFiles();
- if (ArrayUtils.isEmpty(files)) {
- Slog.d(TAG, "No users found on " + volumeUuid);
- return;
- }
-
+ final File[] files = FileUtils
+ .listFilesOrEmpty(Environment.getDataUserDirectory(volumeUuid));
for (File file : files) {
if (!file.isDirectory()) continue;
@@ -15661,12 +15662,8 @@
* another volume.
*/
private void reconcileApps(String volumeUuid) {
- final File[] files = Environment.getDataAppDirectory(volumeUuid).listFiles();
- if (ArrayUtils.isEmpty(files)) {
- Slog.d(TAG, "No apps found on " + volumeUuid);
- return;
- }
-
+ final File[] files = FileUtils
+ .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid));
for (File file : files) {
final boolean isPackage = (isApkFile(file) || file.isDirectory())
&& !PackageInstallerService.isStageName(file.getName());
@@ -15797,7 +15794,12 @@
}
// Now that we're guarded by frozen state, kill app during move
- killApplication(packageName, appId, "move pkg");
+ final long token = Binder.clearCallingIdentity();
+ try {
+ killApplication(packageName, appId, "move pkg");
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
final Bundle extras = new Bundle();
extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 92b9da6..736b153 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -4120,6 +4120,28 @@
pw.print(prefix); pw.print(" pkgFlags="); printFlags(pw, ps.pkgFlags, FLAG_DUMP_SPEC);
pw.println();
+ if (ps.pkg != null && ps.pkg.permissions != null && ps.pkg.permissions.size() > 0) {
+ final ArrayList<PackageParser.Permission> perms = ps.pkg.permissions;
+ pw.print(prefix); pw.println(" declared permissions:");
+ for (int i=0; i<perms.size(); i++) {
+ PackageParser.Permission perm = perms.get(i);
+ if (permissionNames != null
+ && !permissionNames.contains(perm.info.name)) {
+ continue;
+ }
+ pw.print(prefix); pw.print(" "); pw.print(perm.info.name);
+ pw.print(": prot=");
+ pw.print(PermissionInfo.protectionToString(perm.info.protectionLevel));
+ if ((perm.info.flags&PermissionInfo.FLAG_COSTS_MONEY) != 0) {
+ pw.print(", COSTS_MONEY");
+ }
+ if ((perm.info.flags&PermissionInfo.FLAG_INSTALLED) != 0) {
+ pw.print(", INSTALLED");
+ }
+ pw.println();
+ }
+ }
+
if (ps.sharedUser == null || permissionNames != null) {
PermissionsState permissionsState = ps.getPermissionsState();
dumpInstallPermissionsLPr(pw, prefix + " ", permissionNames, permissionsState);
@@ -4155,14 +4177,14 @@
if (cmp != null && cmp.size() > 0) {
pw.print(prefix); pw.println(" disabledComponents:");
for (String s : cmp) {
- pw.print(prefix); pw.print(" "); pw.println(s);
+ pw.print(prefix); pw.print(" "); pw.println(s);
}
}
cmp = ps.getEnabledComponents(user.id);
if (cmp != null && cmp.size() > 0) {
pw.print(prefix); pw.println(" enabledComponents:");
for (String s : cmp) {
- pw.print(prefix); pw.print(" "); pw.println(s);
+ pw.print(prefix); pw.print(" "); pw.println(s);
}
}
}
@@ -4267,11 +4289,14 @@
pw.print(" type="); pw.print(p.type);
pw.print(" prot=");
pw.println(PermissionInfo.protectionToString(p.protectionLevel));
- if (p.packageSetting != null) {
- pw.print(" packageSetting="); pw.println(p.packageSetting);
- }
if (p.perm != null) {
pw.print(" perm="); pw.println(p.perm);
+ if (p.perm.info.flags != PermissionInfo.FLAG_INSTALLED) {
+ pw.print(" flags=0x"); pw.println(Integer.toHexString(p.perm.info.flags));
+ }
+ }
+ if (p.packageSetting != null) {
+ pw.print(" packageSetting="); pw.println(p.packageSetting);
}
if (READ_EXTERNAL_STORAGE.equals(p.name)) {
pw.print(" enforced=");
@@ -4372,24 +4397,32 @@
continue;
}
pw.print(prefix); pw.print(" "); pw.print(permissionState.getName());
- pw.print(", granted="); pw.print(permissionState.isGranted());
- pw.print(", flags="); pw.println(permissionFlagsToString(
- permissionState.getFlags()));
+ pw.print(": granted="); pw.print(permissionState.isGranted());
+ pw.println(permissionFlagsToString(", flags=",
+ permissionState.getFlags()));
}
}
}
- private static String permissionFlagsToString(int flags) {
- StringBuilder flagsString = new StringBuilder();
- flagsString.append("[ ");
+ private static String permissionFlagsToString(String prefix, int flags) {
+ StringBuilder flagsString = null;
while (flags != 0) {
+ if (flagsString == null) {
+ flagsString = new StringBuilder();
+ flagsString.append(prefix);
+ flagsString.append("[ ");
+ }
final int flag = 1 << Integer.numberOfTrailingZeros(flags);
flags &= ~flag;
flagsString.append(PackageManager.permissionFlagToString(flag));
flagsString.append(' ');
}
- flagsString.append(']');
- return flagsString.toString();
+ if (flagsString != null) {
+ flagsString.append(']');
+ return flagsString.toString();
+ } else {
+ return "";
+ }
}
void dumpInstallPermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
@@ -4403,8 +4436,8 @@
continue;
}
pw.print(prefix); pw.print(" "); pw.print(permissionState.getName());
- pw.print(", granted="); pw.print(permissionState.isGranted());
- pw.print(", flags="); pw.println(permissionFlagsToString(
+ pw.print(": granted="); pw.print(permissionState.isGranted());
+ pw.println(permissionFlagsToString(", flags=",
permissionState.getFlags()));
}
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 28cbaab..dc3e2d6 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -119,7 +119,7 @@
import com.android.internal.widget.PointerLocationView;
import com.android.server.LocalServices;
import com.android.server.policy.keyguard.KeyguardServiceDelegate;
-import com.android.server.policy.keyguard.KeyguardServiceDelegate.ShowListener;
+import com.android.server.policy.keyguard.KeyguardServiceDelegate.DrawnListener;
import java.io.File;
import java.io.FileReader;
@@ -323,10 +323,10 @@
mHandler.sendEmptyMessage(MSG_WINDOW_MANAGER_DRAWN_COMPLETE);
}
};
- final ShowListener mKeyguardDelegateCallback = new ShowListener() {
+ final DrawnListener mKeyguardDrawnCallback = new DrawnListener() {
@Override
- public void onShown(IBinder windowToken) {
- if (DEBUG_WAKEUP) Slog.d(TAG, "mKeyguardDelegate.ShowListener.onShown.");
+ public void onDrawn() {
+ if (DEBUG_WAKEUP) Slog.d(TAG, "mKeyguardDelegate.ShowListener.onDrawn.");
mHandler.sendEmptyMessage(MSG_KEYGUARD_DRAWN_COMPLETE);
}
};
@@ -5496,11 +5496,7 @@
}
if (mKeyguardDelegate != null) {
- mKeyguardDelegate.onStartedWakingUp(mKeyguardDelegateCallback);
- // ... eventually calls finishKeyguardDrawn
- } else {
- if (DEBUG_WAKEUP) Slog.d(TAG, "null mKeyguardDelegate: setting mKeyguardDrawComplete.");
- finishKeyguardDrawn();
+ mKeyguardDelegate.onStartedWakingUp();
}
}
@@ -5539,9 +5535,13 @@
if (mKeyguardDelegate != null) {
mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
}
+ mWindowManagerDrawComplete = false;
}
- finishScreenTurningOn();
+ // ... eventually calls finishWindowsDrawn which will finalize our screen turn on
+ // as well as enabling the orientation change logic/sensor.
+ mWindowManagerInternal.waitForAllWindowsDrawn(mWindowManagerDrawCallback,
+ WAITING_FOR_DRAWN_TIMEOUT);
}
// Called on the DisplayManager's DisplayPowerController thread.
@@ -5570,12 +5570,15 @@
mScreenOnFully = false;
mWindowManagerDrawComplete = false;
mScreenOnListener = screenOnListener;
- }
- mWindowManagerInternal.waitForAllWindowsDrawn(mWindowManagerDrawCallback,
- WAITING_FOR_DRAWN_TIMEOUT);
- // ... eventually calls finishWindowsDrawn which will finalize our screen turn on
- // as well as enabling the orientation change logic/sensor.
+ if (mKeyguardDelegate != null) {
+ mKeyguardDelegate.onScreenTurningOn(mKeyguardDrawnCallback);
+ } else {
+ if (DEBUG_WAKEUP) Slog.d(TAG,
+ "null mKeyguardDelegate: setting mKeyguardDrawComplete.");
+ finishKeyguardDrawn();
+ }
+ }
}
private void finishWindowsDrawn() {
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
index 1406789..0f3a199 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -18,9 +18,9 @@
import android.view.WindowManager;
import android.view.WindowManagerPolicy.OnKeyguardExitResult;
+import com.android.internal.policy.IKeyguardDrawnCallback;
import com.android.internal.policy.IKeyguardExitCallback;
import com.android.internal.policy.IKeyguardService;
-import com.android.internal.policy.IKeyguardShowCallback;
/**
* A local class that keeps a cache of keyguard state that can be restored in the event
@@ -35,7 +35,7 @@
private final Context mContext;
private final View mScrim; // shown if keyguard crashes
private final KeyguardState mKeyguardState = new KeyguardState();
- private ShowListener mShowListenerWhenConnect;
+ private DrawnListener mDrawnListenerWhenConnect;
private static final class KeyguardState {
KeyguardState() {
@@ -61,23 +61,23 @@
public boolean bootCompleted;
};
- public interface ShowListener {
- public void onShown(IBinder windowToken);
+ public interface DrawnListener {
+ void onDrawn();
}
// A delegate class to map a particular invocation with a ShowListener object.
- private final class KeyguardShowDelegate extends IKeyguardShowCallback.Stub {
- private ShowListener mShowListener;
+ private final class KeyguardShowDelegate extends IKeyguardDrawnCallback.Stub {
+ private DrawnListener mDrawnListener;
- KeyguardShowDelegate(ShowListener showListener) {
- mShowListener = showListener;
+ KeyguardShowDelegate(DrawnListener drawnListener) {
+ mDrawnListener = drawnListener;
}
@Override
- public void onShown(IBinder windowToken) throws RemoteException {
+ public void onDrawn() throws RemoteException {
if (DEBUG) Log.v(TAG, "**** SHOWN CALLED ****");
- if (mShowListener != null) {
- mShowListener.onShown(windowToken);
+ if (mDrawnListener != null) {
+ mDrawnListener.onDrawn();
}
hideScrim();
}
@@ -141,9 +141,10 @@
// If the system is ready, it means keyguard crashed and restarted.
mKeyguardService.onSystemReady();
// This is used to hide the scrim once keyguard displays.
- mKeyguardService.onStartedWakingUp(new KeyguardShowDelegate(
- mShowListenerWhenConnect));
- mShowListenerWhenConnect = null;
+ mKeyguardService.onStartedWakingUp();
+ mKeyguardService.onScreenTurningOn(
+ new KeyguardShowDelegate(mDrawnListenerWhenConnect));
+ mDrawnListenerWhenConnect = null;
}
if (mKeyguardState.bootCompleted) {
mKeyguardService.onBootCompleted();
@@ -221,16 +222,23 @@
mKeyguardState.dreaming = false;
}
- public void onStartedWakingUp(final ShowListener showListener) {
+ public void onStartedWakingUp() {
if (mKeyguardService != null) {
- if (DEBUG) Log.v(TAG, "onScreenTurnedOn(showListener = " + showListener + ")");
- mKeyguardService.onStartedWakingUp(new KeyguardShowDelegate(showListener));
+ if (DEBUG) Log.v(TAG, "onStartedWakingUp()");
+ mKeyguardService.onStartedWakingUp();
+ }
+ }
+
+ public void onScreenTurningOn(final DrawnListener drawnListener) {
+ if (mKeyguardService != null) {
+ if (DEBUG) Log.v(TAG, "onScreenTurnedOn(showListener = " + drawnListener + ")");
+ mKeyguardService.onScreenTurningOn(new KeyguardShowDelegate(drawnListener));
} else {
// try again when we establish a connection
- Slog.w(TAG, "onScreenTurnedOn(): no keyguard service!");
+ Slog.w(TAG, "onScreenTurningOn(): no keyguard service!");
// This shouldn't happen, but if it does, show the scrim immediately and
// invoke the listener's callback after the service actually connects.
- mShowListenerWhenConnect = showListener;
+ mDrawnListenerWhenConnect = drawnListener;
showScrim();
}
}
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
index 51d59fa..5810a45 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
@@ -22,9 +22,9 @@
import android.os.RemoteException;
import android.util.Slog;
+import com.android.internal.policy.IKeyguardDrawnCallback;
import com.android.internal.policy.IKeyguardExitCallback;
import com.android.internal.policy.IKeyguardService;
-import com.android.internal.policy.IKeyguardShowCallback;
import com.android.internal.policy.IKeyguardStateCallback;
/**
@@ -124,9 +124,18 @@
}
@Override
- public void onStartedWakingUp(IKeyguardShowCallback callback) {
+ public void onStartedWakingUp() {
try {
- mService.onStartedWakingUp(callback);
+ mService.onStartedWakingUp();
+ } catch (RemoteException e) {
+ Slog.w(TAG , "Remote Exception", e);
+ }
+ }
+
+ @Override
+ public void onScreenTurningOn(IKeyguardDrawnCallback callback) {
+ try {
+ mService.onScreenTurningOn(callback);
} catch (RemoteException e) {
Slog.w(TAG , "Remote Exception", e);
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 4f2b1f9..d9828cc 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -10029,70 +10029,70 @@
WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
if (DEBUG_LAYOUT_REPEATS) {
debugLayoutRepeats(
- "dream and commitFinishDrawingLocked true",
- displayContent.pendingLayoutChanges);
+ "dream and commitFinishDrawingLocked true",
+ displayContent.pendingLayoutChanges);
}
}
if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
- "First draw done in potential wallpaper target " + w);
+ "First draw done in potential wallpaper target " + w);
mInnerFields.mWallpaperMayChange = true;
displayContent.pendingLayoutChanges |=
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
if (DEBUG_LAYOUT_REPEATS) {
debugLayoutRepeats(
- "wallpaper and commitFinishDrawingLocked true",
- displayContent.pendingLayoutChanges);
+ "wallpaper and commitFinishDrawingLocked true",
+ displayContent.pendingLayoutChanges);
}
}
}
winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
+ }
- final AppWindowToken atoken = w.mAppToken;
- if (DEBUG_STARTING_WINDOW && atoken != null
- && w == atoken.startingWindow) {
- Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen="
- + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
- + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
+ final AppWindowToken atoken = w.mAppToken;
+ if (DEBUG_STARTING_WINDOW && atoken != null
+ && w == atoken.startingWindow) {
+ Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen="
+ + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
+ + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
+ }
+ if (atoken != null
+ && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
+ if (atoken.lastTransactionSequence != mTransactionSequence) {
+ atoken.lastTransactionSequence = mTransactionSequence;
+ atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
+ atoken.startingDisplayed = false;
}
- if (atoken != null
- && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
- if (atoken.lastTransactionSequence != mTransactionSequence) {
- atoken.lastTransactionSequence = mTransactionSequence;
- atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
- atoken.startingDisplayed = false;
+ if ((w.isOnScreenIgnoringKeyguard()
+ || winAnimator.mAttrType == TYPE_BASE_APPLICATION)
+ && !w.mExiting && !w.mDestroying) {
+ if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
+ Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
+ + ", isAnimating=" + winAnimator.isAnimating());
+ if (!w.isDrawnLw()) {
+ Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceControl
+ + " pv=" + w.mPolicyVisibility
+ + " mDrawState=" + winAnimator.drawStateToString()
+ + " ah=" + w.mAttachedHidden
+ + " th=" + atoken.hiddenRequested
+ + " a=" + winAnimator.mAnimating);
+ }
}
- if ((w.isOnScreenIgnoringKeyguard()
- || winAnimator.mAttrType == TYPE_BASE_APPLICATION)
- && !w.mExiting && !w.mDestroying) {
- if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
- Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
- + ", isAnimating=" + winAnimator.isAnimating());
- if (!w.isDrawnLw()) {
- Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceControl
- + " pv=" + w.mPolicyVisibility
- + " mDrawState=" + winAnimator.drawStateToString()
- + " ah=" + w.mAttachedHidden
- + " th=" + atoken.hiddenRequested
- + " a=" + winAnimator.mAnimating);
+ if (w != atoken.startingWindow) {
+ if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) {
+ atoken.numInterestingWindows++;
+ if (w.isDrawnLw()) {
+ atoken.numDrawnWindows++;
+ if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
+ "tokenMayBeDrawn: " + atoken
+ + " freezingScreen=" + atoken.mAppAnimator.freezingScreen
+ + " mAppFreezing=" + w.mAppFreezing);
+ updateAllDrawn = true;
}
}
- if (w != atoken.startingWindow) {
- if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) {
- atoken.numInterestingWindows++;
- if (w.isDrawnLw()) {
- atoken.numDrawnWindows++;
- if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
- "tokenMayBeDrawn: " + atoken
- + " freezingScreen=" + atoken.mAppAnimator.freezingScreen
- + " mAppFreezing=" + w.mAppFreezing);
- updateAllDrawn = true;
- }
- }
- } else if (w.isDrawnLw()) {
- atoken.startingDisplayed = true;
- }
+ } else if (w.isDrawnLw()) {
+ atoken.startingDisplayed = true;
}
}
}
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 1787b91..4cfa37a 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -49,10 +49,8 @@
import com.android.server.FgThread;
import java.io.File;
-import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.IOException;
-import java.io.PrintWriter;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
@@ -807,8 +805,7 @@
}
private String getDefaultFunctions() {
- return SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY,
- UsbManager.USB_FUNCTION_ADB);
+ return mAdbEnabled ? UsbManager.USB_FUNCTION_ADB : UsbManager.USB_FUNCTION_MTP;
}
public void dump(IndentingPrintWriter pw) {
diff --git a/services/usb/java/com/android/server/usb/UsbHostManager.java b/services/usb/java/com/android/server/usb/UsbHostManager.java
index 6300a9a..965341e 100644
--- a/services/usb/java/com/android/server/usb/UsbHostManager.java
+++ b/services/usb/java/com/android/server/usb/UsbHostManager.java
@@ -231,6 +231,8 @@
mNewConfigurations = null;
mNewInterfaces = null;
mNewEndpoints = null;
+ mNewConfiguration = null;
+ mNewInterface = null;
}
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index b57c413..a8874d0 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -894,6 +894,28 @@
}
@Override
+ public void onLockscreenShown() {
+ enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
+ synchronized (this) {
+ if (mImpl == null) {
+ return;
+ }
+ final long caller = Binder.clearCallingIdentity();
+ try {
+ if (mImpl.mActiveSession != null && mImpl.mActiveSession.mSession != null) {
+ try {
+ mImpl.mActiveSession.mSession.onLockscreenShown();
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to call onLockscreenShown", e);
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(caller);
+ }
+ }
+ }
+
+ @Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
diff --git a/tests/Assist/src/com/android/test/assist/AssistInteractionSession.java b/tests/Assist/src/com/android/test/assist/AssistInteractionSession.java
index 43f1e32..851bda9 100644
--- a/tests/Assist/src/com/android/test/assist/AssistInteractionSession.java
+++ b/tests/Assist/src/com/android/test/assist/AssistInteractionSession.java
@@ -24,6 +24,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.service.voice.VoiceInteractionSession;
+import android.util.Log;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.ViewTreeObserver;
@@ -69,6 +70,7 @@
@Override
public void onCreate() {
+ super.onCreate();
// Simulate slowness of Assist app
try {
Thread.sleep(1000);
@@ -105,6 +107,12 @@
}
}
+ @Override
+ public void onLockscreenShown() {
+ super.onLockscreenShown();
+ Log.i("Assistant", "Lockscreen was shown");
+ }
+
private void playAssistAnimation() {
Interpolator linearOutSlowIn = AnimationUtils.loadInterpolator(mBackground.getContext(),
android.R.interpolator.linear_out_slow_in);