Merge "Ignore empty locale list when diffing Configuration objects"
diff --git a/Android.mk b/Android.mk
index e84b683..505b12d 100644
--- a/Android.mk
+++ b/Android.mk
@@ -173,6 +173,7 @@
core/java/android/hardware/hdmi/IHdmiVendorCommandListener.aidl \
core/java/android/hardware/input/IInputManager.aidl \
core/java/android/hardware/input/IInputDevicesChangedListener.aidl \
+ core/java/android/hardware/input/ITabletModeChangedListener.aidl \
core/java/android/hardware/location/IActivityRecognitionHardware.aidl \
core/java/android/hardware/location/IActivityRecognitionHardwareClient.aidl \
core/java/android/hardware/location/IActivityRecognitionHardwareSink.aidl \
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index e15ba74..67dee7f 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4593,27 +4593,6 @@
}
updateDefaultDensity();
- final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
- if (!Process.isIsolated()) {
- final File cacheDir = appContext.getCacheDir();
-
- if (cacheDir != null) {
- // Provide a usable directory for temporary files
- System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
- } else {
- Log.v(TAG, "Unable to initialize \"java.io.tmpdir\" property due to missing cache directory");
- }
-
- // Use codeCacheDir to store generated/compiled graphics code
- final File codeCacheDir = appContext.getCodeCacheDir();
- if (codeCacheDir != null) {
- setupGraphicsSupport(data.info, codeCacheDir);
- } else {
- Log.e(TAG, "Unable to setupGraphicsSupport due to missing code-cache directory");
- }
- }
-
-
final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24));
DateFormat.set24HourTimePref(is24Hr);
@@ -4685,29 +4664,28 @@
/**
* Initialize the default http proxy in this process for the reasons we set the time zone.
*/
- IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
+ final IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
if (b != null) {
// In pre-boot mode (doing initial launch to collect password), not
// all system is up. This includes the connectivity service, so don't
// crash if we can't get it.
- IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
+ final IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
try {
final ProxyInfo proxyInfo = service.getProxyForNetwork(null);
Proxy.setHttpProxySystemProperty(proxyInfo);
} catch (RemoteException e) {}
}
+ // Instrumentation info affects the class loader, so load it before
+ // setting up the app context.
+ final InstrumentationInfo ii;
if (data.instrumentationName != null) {
- InstrumentationInfo ii = null;
try {
- ii = appContext.getPackageManager().
- getInstrumentationInfo(data.instrumentationName, 0);
+ ii = new ApplicationPackageManager(null, getPackageManager())
+ .getInstrumentationInfo(data.instrumentationName, 0);
} catch (PackageManager.NameNotFoundException e) {
- }
- if (ii == null) {
throw new RuntimeException(
- "Unable to find instrumentation info for: "
- + data.instrumentationName);
+ "Unable to find instrumentation info for: " + data.instrumentationName);
}
mInstrumentationPackageName = ii.packageName;
@@ -4717,13 +4695,32 @@
mInstrumentedAppDir = data.info.getAppDir();
mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
mInstrumentedLibDir = data.info.getLibDir();
+ } else {
+ ii = null;
+ }
- // The app context's info was created against this thread, but
- // the class loader may have already been loaded and cached with
- // outdated paths. Clear it so we can load it again using the
- // instrumentation paths.
- data.info.clearClassLoader();
+ final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
+ if (!Process.isIsolated()) {
+ final File cacheDir = appContext.getCacheDir();
+ if (cacheDir != null) {
+ // Provide a usable directory for temporary files
+ System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
+ } else {
+ Log.v(TAG, "Unable to initialize \"java.io.tmpdir\" property "
+ + "due to missing cache directory");
+ }
+ // Use codeCacheDir to store generated/compiled graphics code
+ final File codeCacheDir = appContext.getCodeCacheDir();
+ if (codeCacheDir != null) {
+ setupGraphicsSupport(data.info, codeCacheDir);
+ } else {
+ Log.e(TAG, "Unable to setupGraphicsSupport due to missing code-cache directory");
+ }
+ }
+
+ // Continue loading instrumentation.
+ if (ii != null) {
final ApplicationInfo instrApp = new ApplicationInfo();
instrApp.packageName = ii.packageName;
instrApp.sourceDir = ii.sourceDir;
@@ -4732,13 +4729,13 @@
instrApp.splitPublicSourceDirs = ii.splitPublicSourceDirs;
instrApp.dataDir = ii.dataDir;
instrApp.nativeLibraryDir = ii.nativeLibraryDir;
- LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
+
+ final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
appContext.getClassLoader(), false, true, false);
- ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
+ final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
try {
-
- java.lang.ClassLoader cl = instrContext.getClassLoader();
+ final ClassLoader cl = instrContext.getClassLoader();
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
} catch (Exception e) {
@@ -4747,18 +4744,17 @@
+ data.instrumentationName + ": " + e.toString(), e);
}
- mInstrumentation.init(this, instrContext, appContext,
- new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher,
- data.instrumentationUiAutomationConnection);
+ final ComponentName component = new ComponentName(ii.packageName, ii.name);
+ mInstrumentation.init(this, instrContext, appContext, component,
+ data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
if (mProfiler.profileFile != null && !ii.handleProfiling
&& mProfiler.profileFd == null) {
mProfiler.handlingProfiling = true;
- File file = new File(mProfiler.profileFile);
+ final File file = new File(mProfiler.profileFile);
file.getParentFile().mkdirs();
Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
}
-
} else {
mInstrumentation = new Instrumentation();
}
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 3b1c60b..c2bf28a 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -255,13 +255,6 @@
return ai.sharedLibraryFiles;
}
- /** @hide */
- public void clearClassLoader() {
- synchronized (this) {
- mClassLoader = null;
- }
- }
-
public ClassLoader getClassLoader() {
synchronized (this) {
if (mClassLoader != null) {
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index 465d142..c8b45c7 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -19,6 +19,7 @@
import android.hardware.input.InputDeviceIdentifier;
import android.hardware.input.KeyboardLayout;
import android.hardware.input.IInputDevicesChangedListener;
+import android.hardware.input.ITabletModeChangedListener;
import android.hardware.input.TouchCalibration;
import android.os.IBinder;
import android.view.InputDevice;
@@ -60,6 +61,9 @@
// Registers an input devices changed listener.
void registerInputDevicesChangedListener(IInputDevicesChangedListener listener);
+ // Registers a tablet mode change listener
+ void registerTabletModeChangedListener(ITabletModeChangedListener listener);
+
// Input device vibrator control.
void vibrate(int deviceId, in long[] pattern, int repeat, IBinder token);
void cancelVibrate(int deviceId, IBinder token);
diff --git a/core/java/android/hardware/input/ITabletModeChangedListener.aidl b/core/java/android/hardware/input/ITabletModeChangedListener.aidl
new file mode 100644
index 0000000..a8559a7
--- /dev/null
+++ b/core/java/android/hardware/input/ITabletModeChangedListener.aidl
@@ -0,0 +1,23 @@
+/*
+ * 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 android.hardware.input;
+
+/** @hide */
+interface ITabletModeChangedListener {
+ /* Called when the device enters or exits tablet mode. */
+ oneway void onTabletModeChanged(long whenNanos, boolean inTabletMode);
+}
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 4292050..bae5757 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -16,6 +16,7 @@
package android.hardware.input;
+import com.android.internal.os.SomeArgs;
import com.android.internal.util.ArrayUtils;
import android.annotation.SdkConstant;
@@ -29,6 +30,7 @@
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.SystemClock;
import android.os.Vibrator;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
@@ -38,6 +40,7 @@
import android.view.InputEvent;
import java.util.ArrayList;
+import java.util.List;
/**
* Provides information about input devices and available key layouts.
@@ -67,6 +70,11 @@
private final ArrayList<InputDeviceListenerDelegate> mInputDeviceListeners =
new ArrayList<InputDeviceListenerDelegate>();
+ // Guarded by mTabletModeLock
+ private final Object mTabletModeLock = new Object();
+ private TabletModeChangedListener mTabletModeChangedListener;
+ private List<OnTabletModeChangedListenerDelegate> mOnTabletModeChangedListeners;
+
/**
* Broadcast Action: Query available keyboard layouts.
* <p>
@@ -332,6 +340,72 @@
}
/**
+ * Register a tablet mode changed listener.
+ *
+ * @param listener The listener to register.
+ * @param handler The handler on which the listener should be invoked, or null
+ * if the listener should be invoked on the calling thread's looper.
+ * @hide
+ */
+ public void registerOnTabletModeChangedListener(
+ OnTabletModeChangedListener listener, Handler handler) {
+ if (listener == null) {
+ throw new IllegalArgumentException("listener must not be null");
+ }
+ synchronized (mTabletModeLock) {
+ if (mOnTabletModeChangedListeners == null) {
+ initializeTabletModeListenerLocked();
+ }
+ int idx = findOnTabletModeChangedListenerLocked(listener);
+ if (idx < 0) {
+ OnTabletModeChangedListenerDelegate d =
+ new OnTabletModeChangedListenerDelegate(listener, handler);
+ mOnTabletModeChangedListeners.add(d);
+ }
+ }
+ }
+
+ /**
+ * Unregister a tablet mode changed listener.
+ *
+ * @param listener The listener to unregister.
+ * @hide
+ */
+ public void unregisterOnTabletModeChangedListener(OnTabletModeChangedListener listener) {
+ if (listener == null) {
+ throw new IllegalArgumentException("listener must not be null");
+ }
+ synchronized (mTabletModeLock) {
+ int idx = findOnTabletModeChangedListenerLocked(listener);
+ if (idx >= 0) {
+ OnTabletModeChangedListenerDelegate d = mOnTabletModeChangedListeners.remove(idx);
+ d.removeCallbacksAndMessages(null);
+ }
+ }
+ }
+
+ private void initializeTabletModeListenerLocked() {
+ final TabletModeChangedListener listener = new TabletModeChangedListener();
+ try {
+ mIm.registerTabletModeChangedListener(listener);
+ } catch (RemoteException ex) {
+ throw new RuntimeException("Could not register tablet mode changed listener", ex);
+ }
+ mTabletModeChangedListener = listener;
+ mOnTabletModeChangedListeners = new ArrayList<>();
+ }
+
+ private int findOnTabletModeChangedListenerLocked(OnTabletModeChangedListener listener) {
+ final int N = mOnTabletModeChangedListeners.size();
+ for (int i = 0; i < N; i++) {
+ if (mOnTabletModeChangedListeners.get(i).mListener == listener) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
* Gets information about all supported keyboard layouts.
* <p>
* The input manager consults the built-in keyboard layouts as well
@@ -770,6 +844,22 @@
return false;
}
+
+ private void onTabletModeChanged(long whenNanos, boolean inTabletMode) {
+ if (DEBUG) {
+ Log.d(TAG, "Received tablet mode changed: "
+ + "whenNanos=" + whenNanos + ", inTabletMode=" + inTabletMode);
+ }
+ synchronized (mTabletModeLock) {
+ final int N = mOnTabletModeChangedListeners.size();
+ for (int i = 0; i < N; i++) {
+ OnTabletModeChangedListenerDelegate listener =
+ mOnTabletModeChangedListeners.get(i);
+ listener.sendTabletModeChanged(whenNanos, inTabletMode);
+ }
+ }
+ }
+
/**
* Gets a vibrator service associated with an input device, assuming it has one.
* @return The vibrator, never null.
@@ -839,6 +929,57 @@
}
}
+ /** @hide */
+ public interface OnTabletModeChangedListener {
+ /**
+ * Called whenever the device goes into or comes out of tablet mode.
+ *
+ * @param whenNanos The time at which the device transitioned into or
+ * out of tablet mode. This is given in nanoseconds in the
+ * {@link SystemClock#uptimeMillis} time base.
+ */
+ void onTabletModeChanged(long whenNanos, boolean inTabletMode);
+ }
+
+ private final class TabletModeChangedListener extends ITabletModeChangedListener.Stub {
+ @Override
+ public void onTabletModeChanged(long whenNanos, boolean inTabletMode) {
+ InputManager.this.onTabletModeChanged(whenNanos, inTabletMode);
+ }
+ }
+
+ private static final class OnTabletModeChangedListenerDelegate extends Handler {
+ private static final int MSG_TABLET_MODE_CHANGED = 0;
+
+ public final OnTabletModeChangedListener mListener;
+
+ public OnTabletModeChangedListenerDelegate(
+ OnTabletModeChangedListener listener, Handler handler) {
+ super(handler != null ? handler.getLooper() : Looper.myLooper());
+ mListener = listener;
+ }
+
+ public void sendTabletModeChanged(long whenNanos, boolean inTabletMode) {
+ SomeArgs args = SomeArgs.obtain();
+ args.argi1 = (int) (whenNanos & 0xFFFFFFFF);
+ args.argi2 = (int) (whenNanos >> 32);
+ args.arg1 = (Boolean) inTabletMode;
+ obtainMessage(MSG_TABLET_MODE_CHANGED, args).sendToTarget();
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_TABLET_MODE_CHANGED:
+ SomeArgs args = (SomeArgs) msg.obj;
+ long whenNanos = (args.argi1 & 0xFFFFFFFFl) | ((long) args.argi2 << 32);
+ boolean inTabletMode = (boolean) args.arg1;
+ mListener.onTabletModeChanged(whenNanos, inTabletMode);
+ break;
+ }
+ }
+ }
+
private final class InputDeviceVibrator extends Vibrator {
private final int mDeviceId;
private final Binder mToken;
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index e77b862..72971e8 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -199,10 +199,7 @@
} else {
userId = UserHandle.myUserId();
}
- IBinder iBinder = ServiceManager.getService(Context.ACCESSIBILITY_SERVICE);
- IAccessibilityManager service = iBinder == null
- ? null : IAccessibilityManager.Stub.asInterface(iBinder);
- sInstance = new AccessibilityManager(context, service, userId);
+ sInstance = new AccessibilityManager(context, null, userId);
}
}
return sInstance;
@@ -219,10 +216,9 @@
*/
public AccessibilityManager(Context context, IAccessibilityManager service, int userId) {
mHandler = new MyHandler(context.getMainLooper());
- mService = service;
mUserId = userId;
synchronized (mLock) {
- tryConnectToServiceLocked();
+ tryConnectToServiceLocked(service);
}
}
@@ -612,17 +608,20 @@
private IAccessibilityManager getServiceLocked() {
if (mService == null) {
- tryConnectToServiceLocked();
+ tryConnectToServiceLocked(null);
}
return mService;
}
- private void tryConnectToServiceLocked() {
- IBinder iBinder = ServiceManager.getService(Context.ACCESSIBILITY_SERVICE);
- if (iBinder == null) {
- return;
+ private void tryConnectToServiceLocked(IAccessibilityManager service) {
+ if (service == null) {
+ IBinder iBinder = ServiceManager.getService(Context.ACCESSIBILITY_SERVICE);
+ if (iBinder == null) {
+ return;
+ }
+ service = IAccessibilityManager.Stub.asInterface(iBinder);
}
- IAccessibilityManager service = IAccessibilityManager.Stub.asInterface(iBinder);
+
try {
final int stateFlags = service.addClient(mClient, mUserId);
setStateLocked(stateFlags);
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 051845f..d96a909 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -232,7 +232,7 @@
public void reportFailedPasswordAttempt(int userId) {
getDevicePolicyManager().reportFailedPasswordAttempt(userId);
getTrustManager().reportUnlockAttempt(false /* authenticated */, userId);
- requireCredentialEntry(userId);
+ requireStrongAuth(StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_WRONG_CREDENTIAL, userId);
}
public void reportSuccessfulPasswordAttempt(int userId) {
@@ -1290,10 +1290,17 @@
*/
public static final int STRONG_AUTH_REQUIRED_AFTER_LOCKOUT = 0x8;
+ /**
+ * Some authentication is required because the user has entered a wrong credential.
+ */
+ public static final int SOME_AUTH_REQUIRED_AFTER_WRONG_CREDENTIAL = 0x10;
+
public static final int DEFAULT = STRONG_AUTH_REQUIRED_AFTER_BOOT;
- final SparseIntArray mStrongAuthRequiredForUser = new SparseIntArray();
+ private static final int ALLOWING_FINGERPRINT = STRONG_AUTH_NOT_REQUIRED
+ | SOME_AUTH_REQUIRED_AFTER_WRONG_CREDENTIAL;
+ private final SparseIntArray mStrongAuthRequiredForUser = new SparseIntArray();
private final H mHandler;
public StrongAuthTracker() {
@@ -1332,7 +1339,7 @@
* current strong authentication requirements.
*/
public boolean isFingerprintAllowedForUser(int userId) {
- return getStrongAuthForUser(userId) == STRONG_AUTH_NOT_REQUIRED;
+ return (getStrongAuthForUser(userId) & ~ALLOWING_FINGERPRINT) == 0;
}
/**
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index b0621e9..d6657dd 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2069,6 +2069,12 @@
<permission android:name="android.permission.SET_KEYBOARD_LAYOUT"
android:protectionLevel="signature" />
+ <!-- Allows an application to monitor changes in tablet mode.
+ <p>Not for use by third-party applications.
+ @hide -->
+ <permission android:name="android.permission.TABLET_MODE_LISTENER"
+ android:protectionLevel="signature" />
+
<!-- Allows an application to request installing packages. Apps
targeting APIs greater than 22 must hold this permission in
order to use {@link android.content.Intent#ACTION_INSTALL_PACKAGE}.
diff --git a/core/tests/coretests/src/android/provider/SettingsProviderTest.java b/core/tests/coretests/src/android/provider/SettingsProviderTest.java
index 2615a28..e6d3158 100644
--- a/core/tests/coretests/src/android/provider/SettingsProviderTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsProviderTest.java
@@ -28,7 +28,6 @@
import android.net.Uri;
import android.os.UserHandle;
import android.os.UserManager;
-import android.provider.Settings;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
@@ -37,7 +36,6 @@
import java.util.List;
/** Unit test for SettingsProvider. */
-@Suppress // Failing.
public class SettingsProviderTest extends AndroidTestCase {
@MediumTest
public void testNameValueCache() {
@@ -53,84 +51,108 @@
assertEquals(1, r.delete(Settings.Secure.getUriFor("test_service"), null, null));
assertEquals(null, Settings.Secure.getString(r, "test_service"));
- // Try all the same things in the System table
- Settings.System.putString(r, "test_setting", "Value");
- assertEquals("Value", Settings.System.getString(r, "test_setting"));
-
- Settings.System.putString(r, "test_setting", "New");
- assertEquals("New", Settings.System.getString(r, "test_setting"));
-
- assertEquals(1, r.delete(Settings.System.getUriFor("test_setting"), null, null));
- assertEquals(null, Settings.System.getString(r, "test_setting"));
+ // Apps should not be able to use System settings.
+ try {
+ Settings.System.putString(r, "test_setting", "Value");
+ fail("IllegalArgumentException expected");
+ } catch (java.lang.IllegalArgumentException e) {
+ // expected
+ }
}
@MediumTest
- public void testRowNameContentUri() {
+ public void testRowNameContentUriForSecure() {
+ final String testKey = "testRowNameContentUriForSecure";
+ final String testValue = "testValue";
+ final String secondTestValue = "testValueNew";
+
+ try {
+ testRowNameContentUri(Settings.Secure.CONTENT_URI, Settings.Secure.NAME,
+ Settings.Secure.VALUE, testKey, testValue, secondTestValue);
+ } finally {
+ // clean up
+ Settings.Secure.putString(getContext().getContentResolver(), testKey, null);
+ }
+ }
+
+ @MediumTest
+ public void testRowNameContentUriForSystem() {
+ final String testKey = Settings.System.VIBRATE_ON;
+ assertTrue("Settings.System.PUBLIC_SETTINGS cannot be empty. We need to use one of it"
+ + " for testing. Only settings key in this collection will be accepted by the"
+ + " framework.", Settings.System.PUBLIC_SETTINGS.contains(testKey));
+ final String testValue = "0";
+ final String secondTestValue = "1";
+ final String oldValue =
+ Settings.System.getString(getContext().getContentResolver(), testKey);
+
+ try {
+ testRowNameContentUri(Settings.System.CONTENT_URI, Settings.System.NAME,
+ Settings.System.VALUE, testKey, testValue, secondTestValue);
+ } finally {
+ // restore old value
+ if (oldValue != null) {
+ Settings.System.putString(getContext().getContentResolver(), testKey, oldValue);
+ }
+ }
+ }
+
+ private void testRowNameContentUri(Uri table, String nameField, String valueField,
+ String testKey, String testValue, String secondTestValue) {
ContentResolver r = getContext().getContentResolver();
- assertEquals("content://settings/system/test_setting",
- Settings.System.getUriFor("test_setting").toString());
- assertEquals("content://settings/secure/test_service",
- Settings.Secure.getUriFor("test_service").toString());
+ ContentValues v = new ContentValues();
+ v.put(nameField, testKey);
+ v.put(valueField, testValue);
- // These tables use the row name (not ID) as their content URI.
- Uri tables[] = { Settings.System.CONTENT_URI, Settings.Secure.CONTENT_URI };
- for (Uri table : tables) {
- ContentValues v = new ContentValues();
- v.put(Settings.System.NAME, "test_key");
- v.put(Settings.System.VALUE, "Test");
- Uri uri = r.insert(table, v);
- assertEquals(table.toString() + "/test_key", uri.toString());
+ r.insert(table, v);
+ Uri uri = Uri.parse(table.toString() + "/" + testKey);
- // Query with a specific URI and no WHERE clause succeeds.
- Cursor c = r.query(uri, null, null, null, null);
- try {
- assertTrue(c.moveToNext());
- assertEquals("test_key", c.getString(c.getColumnIndex(Settings.System.NAME)));
- assertEquals("Test", c.getString(c.getColumnIndex(Settings.System.VALUE)));
- assertFalse(c.moveToNext());
- } finally {
- c.close();
- }
-
- // Query with a specific URI and a WHERE clause fails.
- try {
- r.query(uri, null, "1", null, null);
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException e) {
- if (!e.toString().contains("WHERE clause")) throw e;
- }
-
- // Query with a tablewide URI and a WHERE clause succeeds.
- c = r.query(table, null, "name='test_key'", null, null);
- try {
- assertTrue(c.moveToNext());
- assertEquals("test_key", c.getString(c.getColumnIndex(Settings.System.NAME)));
- assertEquals("Test", c.getString(c.getColumnIndex(Settings.System.VALUE)));
- assertFalse(c.moveToNext());
- } finally {
- c.close();
- }
-
- v = new ContentValues();
- v.put(Settings.System.VALUE, "Toast");
- assertEquals(1, r.update(uri, v, null, null));
-
- c = r.query(uri, null, null, null, null);
- try {
- assertTrue(c.moveToNext());
- assertEquals("test_key", c.getString(c.getColumnIndex(Settings.System.NAME)));
- assertEquals("Toast", c.getString(c.getColumnIndex(Settings.System.VALUE)));
- assertFalse(c.moveToNext());
- } finally {
- c.close();
- }
-
- assertEquals(1, r.delete(uri, null, null));
+ // Query with a specific URI and no WHERE clause succeeds.
+ Cursor c = r.query(uri, null, null, null, null);
+ try {
+ assertTrue(c.moveToNext());
+ assertEquals(testKey, c.getString(c.getColumnIndex(nameField)));
+ assertEquals(testValue, c.getString(c.getColumnIndex(valueField)));
+ assertFalse(c.moveToNext());
+ } finally {
+ c.close();
}
- assertEquals(null, Settings.System.getString(r, "test_key"));
- assertEquals(null, Settings.Secure.getString(r, "test_key"));
+ // Query with a specific URI and a WHERE clause fails.
+ try {
+ r.query(uri, null, "1", null, null);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ // Query with a tablewide URI and a WHERE clause succeeds.
+ c = r.query(table, null, "name='" + testKey + "'", null, null);
+ try {
+ assertTrue(c.moveToNext());
+ assertEquals(testKey, c.getString(c.getColumnIndex(nameField)));
+ assertEquals(testValue, c.getString(c.getColumnIndex(valueField)));
+ assertFalse(c.moveToNext());
+ } finally {
+ c.close();
+ }
+
+ v = new ContentValues();
+ // NAME is still needed, although the uri should be specific enough. Why?
+ v.put(nameField, testKey);
+ v.put(valueField, secondTestValue);
+ assertEquals(1, r.update(uri, v, null, null));
+
+ c = r.query(uri, null, null, null, null);
+ try {
+ assertTrue(c.moveToNext());
+ assertEquals(testKey, c.getString(c.getColumnIndex(nameField)));
+ assertEquals(secondTestValue, c.getString(c.getColumnIndex(valueField)));
+ assertFalse(c.moveToNext());
+ } finally {
+ c.close();
+ }
}
@MediumTest
@@ -139,7 +161,7 @@
ContentResolver r = getContext().getContentResolver();
// Make sure there's an owner
- assertTrue(findUser(um, UserHandle.USER_OWNER));
+ assertTrue(findUser(um, UserHandle.USER_SYSTEM));
// create a new user to use for testing
UserInfo otherUser = um.createUser("TestUser1", UserInfo.FLAG_GUEST);
@@ -148,21 +170,17 @@
assertNotSame("Current calling user id should not be the new guest user",
otherUser.id, UserHandle.getCallingUserId());
- Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "gps");
- Settings.Secure.putStringForUser(r,
- Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "network", otherUser.id);
+ final String testKey = "testSettingsChangeForOtherUser";
+ final String testValue1 = "value1";
+ final String testValue2 = "value2";
+ Settings.Secure.putString(r, testKey, testValue1);
+ Settings.Secure.putStringForUser(r, testKey, testValue2, otherUser.id);
- assertEquals("gps",
- Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
- assertEquals("network", Settings.Secure.getStringForUser(
- r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, otherUser.id));
+ assertEquals(testValue1, Settings.Secure.getString(r, testKey));
+ assertEquals(testValue2, Settings.Secure.getStringForUser(r, testKey, otherUser.id));
assertNotSame("Current calling user id should not be the new guest user",
otherUser.id, UserHandle.getCallingUserId());
- Settings.Secure.setLocationProviderEnabledForUser(r, "network", false, otherUser.id);
- assertEquals("", Settings.Secure.getStringForUser(
- r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, otherUser.id));
-
} finally {
// Tidy up
um.removeUser(otherUser.id);
@@ -170,6 +188,7 @@
}
@MediumTest
+ @Suppress // Settings.Bookmarks uses a query format that's not supported now.
public void testRowNumberContentUri() {
ContentResolver r = getContext().getContentResolver();
@@ -196,47 +215,56 @@
public void testParseProviderList() {
ContentResolver r = getContext().getContentResolver();
- // Make sure we get out what we put in.
- Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
- "test1,test2,test3");
- assertEquals(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED),
- "test1,test2,test3");
-
+ // We only accept "+value" and "-value"
// Test adding a value
- Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
- "");
Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "+test1");
- assertEquals("test1",
- Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
+ assertTrue(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+ .contains("test1"));
// Test adding a second value
Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "+test2");
- assertEquals("test1,test2",
- Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
+ assertTrue(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+ .contains("test1"));
+ assertTrue(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+ .contains("test2"));
// Test adding a third value
Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "+test3");
- assertEquals("test1,test2,test3",
- Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
+ assertTrue(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+ .contains("test1"));
+ assertTrue(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+ .contains("test2"));
+ assertTrue(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+ .contains("test3"));
// Test deleting the first value in a 3 item list
Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "-test1");
- assertEquals("test2,test3",
- Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
+ assertFalse(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+ .contains("test1"));
// Test deleting the middle value in a 3 item list
- Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
- "test1,test2,test3");
- Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "-test2");
- assertEquals("test1,test3",
- Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
+ Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "+test4");
+ assertTrue(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+ .contains("test2"));
+ assertTrue(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+ .contains("test3"));
+ assertTrue(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+ .contains("test4"));
+ Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "-test3");
+ assertFalse(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+ .contains("test3"));
// Test deleting the last value in a 3 item list
- Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
- "test1,test2,test3");
- Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "-test3");
- assertEquals("test1,test2",
- Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
+ Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "+test5");
+ assertTrue(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+ .contains("test2"));
+ assertTrue(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+ .contains("test4"));
+ assertTrue(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+ .contains("test5"));
+ Settings.Secure.putString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "-test5");
+ assertFalse(Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
+ .contains("test5"));
}
private boolean findUser(UserManager um, int userHandle) {
@@ -254,7 +282,7 @@
ContentResolver r = getContext().getContentResolver();
// Make sure there's an owner
- assertTrue(findUser(um, UserHandle.USER_OWNER));
+ assertTrue(findUser(um, UserHandle.USER_SYSTEM));
// create a new user to use for testing
UserInfo user = um.createUser("TestUser1", UserInfo.FLAG_GUEST);
@@ -266,12 +294,12 @@
final int SELF_VALUE = 40;
final int OTHER_VALUE = 27;
- Settings.System.putInt(r, TEST_KEY, SELF_VALUE);
- Settings.System.putIntForUser(r, TEST_KEY, OTHER_VALUE, user.id);
+ Settings.Secure.putInt(r, TEST_KEY, SELF_VALUE);
+ Settings.Secure.putIntForUser(r, TEST_KEY, OTHER_VALUE, user.id);
// Verify that they read back as intended
- int myValue = Settings.System.getInt(r, TEST_KEY, 0);
- int otherValue = Settings.System.getIntForUser(r, TEST_KEY, 0, user.id);
+ int myValue = Settings.Secure.getInt(r, TEST_KEY, 0);
+ int otherValue = Settings.Secure.getIntForUser(r, TEST_KEY, 0, user.id);
assertTrue("Running as user " + UserHandle.myUserId()
+ " and reading/writing as user " + user.id
+ ", expected to read " + SELF_VALUE + " but got " + myValue,
@@ -310,7 +338,8 @@
assertCanBeHandled(new Intent(Settings.ACTION_MEMORY_CARD_SETTINGS));
assertCanBeHandled(new Intent(Settings.ACTION_NETWORK_OPERATOR_SETTINGS));
assertCanBeHandled(new Intent(Settings.ACTION_PRIVACY_SETTINGS));
- assertCanBeHandled(new Intent(Settings.ACTION_QUICK_LAUNCH_SETTINGS));
+ //TODO: seems no one is using this anymore.
+// assertCanBeHandled(new Intent(Settings.ACTION_QUICK_LAUNCH_SETTINGS));
assertCanBeHandled(new Intent(Settings.ACTION_SEARCH_SETTINGS));
assertCanBeHandled(new Intent(Settings.ACTION_SECURITY_SETTINGS));
assertCanBeHandled(new Intent(Settings.ACTION_SETTINGS));
diff --git a/graphics/java/android/graphics/drawable/AnimationDrawable.java b/graphics/java/android/graphics/drawable/AnimationDrawable.java
index e1975c9..521c74b 100644
--- a/graphics/java/android/graphics/drawable/AnimationDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java
@@ -105,10 +105,12 @@
/**
* Sets whether this AnimationDrawable is visible.
* <p>
- * When the drawable becomes invisible, it will pause its animation. A
- * subsequent change to visible with <code>restart</code> set to true will
- * restart the animation from the first frame. If <code>restart</code> is
- * false, the animation will resume from the most recent frame.
+ * When the drawable becomes invisible, it will pause its animation. A subsequent change to
+ * visible with <code>restart</code> set to true will restart the animation from the
+ * first frame. If <code>restart</code> is false, the drawable will resume from the most recent
+ * frame. If the drawable has already reached the last frame, it will then loop back to the
+ * first frame, unless it's a one shot drawable (set through {@link #setOneShot(boolean)}),
+ * in which case, it will stay on the last frame.
*
* @param visible true if visible, false otherwise
* @param restart when visible, true to force the animation to restart
@@ -120,7 +122,7 @@
final boolean changed = super.setVisible(visible, restart);
if (visible) {
if (restart || changed) {
- boolean startFromZero = restart || !mRunning ||
+ boolean startFromZero = restart || (!mRunning && !mAnimationState.mOneShot) ||
mCurFrame >= mAnimationState.getChildCount();
setFrame(startFromZero ? 0 : mCurFrame, true, mAnimating);
}
@@ -131,7 +133,7 @@
}
/**
- * Starts the animation, looping if necessary. This method has no effect
+ * Starts the animation from the first frame, looping if necessary. This method has no effect
* if the animation is running.
* <p>
* <strong>Note:</strong> Do not call this in the
@@ -158,7 +160,7 @@
}
/**
- * Stops the animation. This method has no effect if the animation is not
+ * Stops the animation at the current frame. This method has no effect if the animation is not
* running.
*
* @see #isRunning()
@@ -169,6 +171,7 @@
mAnimating = false;
if (isRunning()) {
+ mCurFrame = 0;
unscheduleSelf(this);
}
}
@@ -196,7 +199,6 @@
@Override
public void unscheduleSelf(Runnable what) {
- mCurFrame = 0;
mRunning = false;
super.unscheduleSelf(what);
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/MultiSelectManager.java b/packages/DocumentsUI/src/com/android/documentsui/MultiSelectManager.java
index 4284f6f..30a5a47 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/MultiSelectManager.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/MultiSelectManager.java
@@ -339,7 +339,7 @@
}
handlePositionChanged(position, metaState);
- return false;
+ return true;
}
/**
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index cfc232c..b752c9b 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -1348,9 +1348,7 @@
*/
private void handleKeyguardReset() {
if (DEBUG) Log.d(TAG, "handleKeyguardReset");
- if (!isUnlockingWithFingerprintAllowed()) {
- updateFingerprintListeningState();
- }
+ updateFingerprintListeningState();
}
/**
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 5a14967..ee296d9 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -109,7 +109,7 @@
static String dbNameForUser(final int userHandle) {
// The owner gets the unadorned db name;
- if (userHandle == UserHandle.USER_OWNER) {
+ if (userHandle == UserHandle.USER_SYSTEM) {
return DATABASE_NAME;
} else {
// Place the database in the user-specific data tree so that it's
@@ -186,8 +186,8 @@
createSecureTable(db);
- // Only create the global table for the singleton 'owner' user
- if (mUserHandle == UserHandle.USER_OWNER) {
+ // Only create the global table for the singleton 'owner/system' user
+ if (mUserHandle == UserHandle.USER_SYSTEM) {
createGlobalTable(db);
}
@@ -1252,7 +1252,7 @@
if (upgradeVersion == 82) {
// Move to per-user settings dbs
- if (mUserHandle == UserHandle.USER_OWNER) {
+ if (mUserHandle == UserHandle.USER_SYSTEM) {
db.beginTransaction();
SQLiteStatement stmt = null;
@@ -1306,7 +1306,7 @@
}
if (upgradeVersion == 84) {
- if (mUserHandle == UserHandle.USER_OWNER) {
+ if (mUserHandle == UserHandle.USER_SYSTEM) {
db.beginTransaction();
SQLiteStatement stmt = null;
try {
@@ -1331,7 +1331,7 @@
}
if (upgradeVersion == 85) {
- if (mUserHandle == UserHandle.USER_OWNER) {
+ if (mUserHandle == UserHandle.USER_SYSTEM) {
db.beginTransaction();
try {
// Fix up the migration, ignoring already-migrated elements, to snap up to
@@ -1348,7 +1348,7 @@
}
if (upgradeVersion == 86) {
- if (mUserHandle == UserHandle.USER_OWNER) {
+ if (mUserHandle == UserHandle.USER_SYSTEM) {
db.beginTransaction();
try {
String[] settingsToMove = {
@@ -1367,7 +1367,7 @@
}
if (upgradeVersion == 87) {
- if (mUserHandle == UserHandle.USER_OWNER) {
+ if (mUserHandle == UserHandle.USER_SYSTEM) {
db.beginTransaction();
try {
String[] settingsToMove = {
@@ -1386,7 +1386,7 @@
}
if (upgradeVersion == 88) {
- if (mUserHandle == UserHandle.USER_OWNER) {
+ if (mUserHandle == UserHandle.USER_SYSTEM) {
db.beginTransaction();
try {
String[] settingsToMove = {
@@ -1432,7 +1432,7 @@
}
if (upgradeVersion == 89) {
- if (mUserHandle == UserHandle.USER_OWNER) {
+ if (mUserHandle == UserHandle.USER_SYSTEM) {
db.beginTransaction();
try {
String[] prefixesToMove = {
@@ -1452,7 +1452,7 @@
}
if (upgradeVersion == 90) {
- if (mUserHandle == UserHandle.USER_OWNER) {
+ if (mUserHandle == UserHandle.USER_SYSTEM) {
db.beginTransaction();
try {
String[] systemToGlobal = {
@@ -1485,7 +1485,7 @@
}
if (upgradeVersion == 91) {
- if (mUserHandle == UserHandle.USER_OWNER) {
+ if (mUserHandle == UserHandle.USER_SYSTEM) {
db.beginTransaction();
try {
// Move ringer mode from system to global settings
@@ -1505,7 +1505,7 @@
try {
stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
+ " VALUES(?,?);");
- if (mUserHandle == UserHandle.USER_OWNER) {
+ if (mUserHandle == UserHandle.USER_SYSTEM) {
// consider existing primary users to have made it through user setup
// if the globally-scoped device-provisioned bit is set
// (indicating they already made it through setup as primary)
@@ -1526,7 +1526,7 @@
if (upgradeVersion == 93) {
// Redo this step, since somehow it didn't work the first time for some users
- if (mUserHandle == UserHandle.USER_OWNER) {
+ if (mUserHandle == UserHandle.USER_SYSTEM) {
db.beginTransaction();
try {
// Migrate now-global settings
@@ -1547,7 +1547,7 @@
if (upgradeVersion == 94) {
// Add wireless charging started sound setting
- if (mUserHandle == UserHandle.USER_OWNER) {
+ if (mUserHandle == UserHandle.USER_SYSTEM) {
db.beginTransaction();
SQLiteStatement stmt = null;
try {
@@ -1565,7 +1565,7 @@
}
if (upgradeVersion == 95) {
- if (mUserHandle == UserHandle.USER_OWNER) {
+ if (mUserHandle == UserHandle.USER_SYSTEM) {
db.beginTransaction();
try {
String[] settingsToMove = { Settings.Global.BUGREPORT_IN_POWER_MENU };
@@ -1584,7 +1584,7 @@
}
if (upgradeVersion == 97) {
- if (mUserHandle == UserHandle.USER_OWNER) {
+ if (mUserHandle == UserHandle.USER_SYSTEM) {
db.beginTransaction();
SQLiteStatement stmt = null;
try {
@@ -1613,7 +1613,7 @@
if (upgradeVersion == 100) {
// note: LOCK_SCREEN_SHOW_NOTIFICATIONS now handled in version 106
- if (mUserHandle == UserHandle.USER_OWNER) {
+ if (mUserHandle == UserHandle.USER_SYSTEM) {
db.beginTransaction();
SQLiteStatement stmt = null;
try {
@@ -1631,7 +1631,7 @@
}
if (upgradeVersion == 101) {
- if (mUserHandle == UserHandle.USER_OWNER) {
+ if (mUserHandle == UserHandle.USER_SYSTEM) {
db.beginTransaction();
SQLiteStatement stmt = null;
try {
@@ -1653,7 +1653,7 @@
try {
// The INSTALL_NON_MARKET_APPS setting is becoming per-user rather
// than device-global.
- if (mUserHandle == UserHandle.USER_OWNER) {
+ if (mUserHandle == UserHandle.USER_SYSTEM) {
// In the owner user, the global table exists so we can migrate the
// entry from there to the secure table, preserving its value.
String[] globalToSecure = {
@@ -1693,7 +1693,7 @@
}
if (upgradeVersion < 105) {
- if (mUserHandle == UserHandle.USER_OWNER) {
+ if (mUserHandle == UserHandle.USER_SYSTEM) {
db.beginTransaction();
SQLiteStatement stmt = null;
try {
@@ -1719,7 +1719,7 @@
+ " VALUES(?,?);");
loadIntegerSetting(stmt, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
R.integer.def_lock_screen_show_notifications);
- if (mUserHandle == UserHandle.USER_OWNER) {
+ if (mUserHandle == UserHandle.USER_SYSTEM) {
final int oldShow = getIntValueFromTable(db,
TABLE_GLOBAL, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, -1);
if (oldShow >= 0) {
@@ -1741,7 +1741,7 @@
if (upgradeVersion < 107) {
// Add trusted sound setting
- if (mUserHandle == UserHandle.USER_OWNER) {
+ if (mUserHandle == UserHandle.USER_SYSTEM) {
db.beginTransaction();
SQLiteStatement stmt = null;
try {
@@ -1816,7 +1816,7 @@
if (upgradeVersion < 111) {
// reset ringer mode, so it doesn't force zen mode to follow
- if (mUserHandle == UserHandle.USER_OWNER) {
+ if (mUserHandle == UserHandle.USER_SYSTEM) {
db.beginTransaction();
SQLiteStatement stmt = null;
try {
@@ -1833,7 +1833,7 @@
}
if (upgradeVersion < 112) {
- if (mUserHandle == UserHandle.USER_OWNER) {
+ if (mUserHandle == UserHandle.USER_SYSTEM) {
// When device name was added, we went with Manufacturer + Model, device name should
// actually be Model only.
// Update device name to Model if it wasn't modified by user.
@@ -1874,7 +1874,7 @@
// We skipped 114 to handle a merge conflict with the introduction of theater mode.
if (upgradeVersion < 115) {
- if (mUserHandle == UserHandle.USER_OWNER) {
+ if (mUserHandle == UserHandle.USER_SYSTEM) {
db.beginTransaction();
SQLiteStatement stmt = null;
try {
@@ -1892,7 +1892,7 @@
}
if (upgradeVersion < 116) {
- if (mUserHandle == UserHandle.USER_OWNER) {
+ if (mUserHandle == UserHandle.USER_SYSTEM) {
db.beginTransaction();
SQLiteStatement stmt = null;
try {
@@ -2066,7 +2066,7 @@
LockPatternUtils lpu = new LockPatternUtils(mContext);
List<LockPatternView.Cell> cellPattern =
LockPatternUtils.stringToPattern(lockPattern);
- lpu.saveLockPattern(cellPattern, null, UserHandle.USER_OWNER);
+ lpu.saveLockPattern(cellPattern, null, UserHandle.USER_SYSTEM);
} catch (IllegalArgumentException e) {
// Don't want corrupted lock pattern to hang the reboot process
}
@@ -2343,8 +2343,8 @@
private void loadSettings(SQLiteDatabase db) {
loadSystemSettings(db);
loadSecureSettings(db);
- // The global table only exists for the 'owner' user
- if (mUserHandle == UserHandle.USER_OWNER) {
+ // The global table only exists for the 'owner/system' user
+ if (mUserHandle == UserHandle.USER_SYSTEM) {
loadGlobalSettings(db);
}
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index 952b220..1d71346 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -123,7 +123,8 @@
}
if (sBroadcastOnRestore.contains(name)) {
- oldValue = table.lookup(cr, name, UserHandle.USER_OWNER);
+ // TODO: http://b/22388012
+ oldValue = table.lookup(cr, name, UserHandle.USER_SYSTEM);
sendBroadcast = true;
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 73971ad..8b1caf9 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -18,7 +18,7 @@
import android.Manifest;
import android.app.ActivityManager;
-import android.app.AppOpsManager;
+import android.app.AppGlobals;
import android.app.backup.BackupManager;
import android.content.BroadcastReceiver;
import android.content.ContentProvider;
@@ -27,6 +27,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
@@ -47,6 +48,7 @@
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.Process;
+import android.os.RemoteException;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
@@ -208,13 +210,13 @@
private volatile UserManager mUserManager;
// We have to call in the package manager with no lock held,
- private volatile PackageManager mPackageManager;
+ private volatile IPackageManager mPackageManager;
@Override
public boolean onCreate() {
synchronized (mLock) {
- mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
- mPackageManager = getContext().getPackageManager();
+ mUserManager = UserManager.get(getContext());
+ mPackageManager = AppGlobals.getPackageManager();
mSettingsRegistry = new SettingsRegistry();
}
registerBroadcastReceivers();
@@ -496,7 +498,7 @@
}
private void dumpForUser(int userId, PrintWriter pw) {
- if (userId == UserHandle.USER_OWNER) {
+ if (userId == UserHandle.USER_SYSTEM) {
pw.println("GLOBAL SETTINGS (user " + userId + ")");
Cursor globalCursor = getAllGlobalSettings(ALL_COLUMNS);
dumpSettings(globalCursor, pw);
@@ -547,7 +549,7 @@
@Override
public void onReceive(Context context, Intent intent) {
final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
- UserHandle.USER_OWNER);
+ UserHandle.USER_SYSTEM);
switch (intent.getAction()) {
case Intent.ACTION_USER_REMOVED: {
@@ -584,7 +586,7 @@
synchronized (mLock) {
// Get the settings.
SettingsState settingsState = mSettingsRegistry.getSettingsLocked(
- SettingsRegistry.SETTINGS_TYPE_GLOBAL, UserHandle.USER_OWNER);
+ SettingsRegistry.SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
List<String> names = settingsState.getSettingNamesLocked();
@@ -612,7 +614,7 @@
// Get the value.
synchronized (mLock) {
return mSettingsRegistry.getSettingLocked(SettingsRegistry.SETTINGS_TYPE_GLOBAL,
- UserHandle.USER_OWNER, name);
+ UserHandle.USER_SYSTEM, name);
}
}
@@ -656,19 +658,19 @@
case MUTATION_OPERATION_INSERT: {
return mSettingsRegistry
.insertSettingLocked(SettingsRegistry.SETTINGS_TYPE_GLOBAL,
- UserHandle.USER_OWNER, name, value, getCallingPackage());
+ UserHandle.USER_SYSTEM, name, value, getCallingPackage());
}
case MUTATION_OPERATION_DELETE: {
return mSettingsRegistry.deleteSettingLocked(
SettingsRegistry.SETTINGS_TYPE_GLOBAL,
- UserHandle.USER_OWNER, name);
+ UserHandle.USER_SYSTEM, name);
}
case MUTATION_OPERATION_UPDATE: {
return mSettingsRegistry
.updateSettingLocked(SettingsRegistry.SETTINGS_TYPE_GLOBAL,
- UserHandle.USER_OWNER, name, value, getCallingPackage());
+ UserHandle.USER_SYSTEM, name, value, getCallingPackage());
}
}
}
@@ -903,7 +905,7 @@
}
// Enforce what the calling package can mutate the system settings.
- enforceRestrictedSystemSettingsMutationForCallingPackage(operation, name);
+ enforceRestrictedSystemSettingsMutationForCallingPackage(operation, name, runAsUserId);
// Resolve the userId on whose behalf the call is made.
final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(runAsUserId);
@@ -1001,7 +1003,7 @@
}
private void enforceRestrictedSystemSettingsMutationForCallingPackage(int operation,
- String name) {
+ String name, int userId) {
// System/root/shell can mutate whatever secure settings they want.
final int callingUid = Binder.getCallingUid();
if (callingUid == android.os.Process.SYSTEM_UID
@@ -1019,7 +1021,7 @@
}
// The calling package is already verified.
- PackageInfo packageInfo = getCallingPackageInfoOrThrow();
+ PackageInfo packageInfo = getCallingPackageInfoOrThrow(userId);
// Privileged apps can do whatever they want.
if ((packageInfo.applicationInfo.privateFlags
@@ -1039,7 +1041,7 @@
}
// The calling package is already verified.
- PackageInfo packageInfo = getCallingPackageInfoOrThrow();
+ PackageInfo packageInfo = getCallingPackageInfoOrThrow(userId);
// Privileged apps can do whatever they want.
if ((packageInfo.applicationInfo.privateFlags &
@@ -1053,17 +1055,17 @@
}
}
- private PackageInfo getCallingPackageInfoOrThrow() {
+ private PackageInfo getCallingPackageInfoOrThrow(int userId) {
try {
- return mPackageManager.getPackageInfo(getCallingPackage(), 0);
- } catch (PackageManager.NameNotFoundException e) {
+ return mPackageManager.getPackageInfo(getCallingPackage(), 0, userId);
+ } catch (RemoteException e) {
throw new IllegalStateException("Calling package doesn't exist");
}
}
private int getGroupParentLocked(int userId) {
// Most frequent use case.
- if (userId == UserHandle.USER_OWNER) {
+ if (userId == UserHandle.USER_SYSTEM) {
return userId;
}
// We are in the same process with the user manager and the returned
@@ -1401,8 +1403,8 @@
migrateLegacySettingsForUserIfNeededLocked(userId);
// Ensure global settings loaded if owner.
- if (userId == UserHandle.USER_OWNER) {
- final int globalKey = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_OWNER);
+ if (userId == UserHandle.USER_SYSTEM) {
+ final int globalKey = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
ensureSettingsStateLocked(globalKey);
}
@@ -1541,7 +1543,7 @@
private void migrateAllLegacySettingsIfNeeded() {
synchronized (mLock) {
- final int key = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_OWNER);
+ final int key = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
File globalFile = getSettingsFile(key);
if (globalFile.exists()) {
return;
@@ -1591,7 +1593,7 @@
private void migrateLegacySettingsForUserLocked(DatabaseHelper dbHelper,
SQLiteDatabase database, int userId) {
// Move over the global settings if owner.
- if (userId == UserHandle.USER_OWNER) {
+ if (userId == UserHandle.USER_SYSTEM) {
final int globalKey = makeKey(SETTINGS_TYPE_GLOBAL, userId);
ensureSettingsStateLocked(globalKey);
SettingsState globalSettings = mSettingsStates.get(globalKey);
@@ -1898,7 +1900,7 @@
}
// Set the global settings version if owner.
- if (mUserId == UserHandle.USER_OWNER) {
+ if (mUserId == UserHandle.USER_SYSTEM) {
SettingsState globalSettings = getSettingsLocked(
SettingsRegistry.SETTINGS_TYPE_GLOBAL, mUserId);
globalSettings.setVersionLocked(newVersion);
@@ -1914,7 +1916,7 @@
}
private SettingsState getGlobalSettingsLocked() {
- return getSettingsLocked(SETTINGS_TYPE_GLOBAL, UserHandle.USER_OWNER);
+ return getSettingsLocked(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
}
private SettingsState getSecureSettingsLocked(int userId) {
@@ -1960,7 +1962,7 @@
// v119: Reset zen + ringer mode.
if (currentVersion == 118) {
- if (userId == UserHandle.USER_OWNER) {
+ if (userId == UserHandle.USER_SYSTEM) {
final SettingsState globalSettings = getGlobalSettingsLocked();
globalSettings.updateSettingLocked(Settings.Global.ZEN_MODE,
Integer.toString(Settings.Global.ZEN_MODE_OFF),
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java
index c7cc89b..8e56f47 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java
@@ -48,7 +48,7 @@
Settings.NameValueTable.NAME, Settings.NameValueTable.VALUE
};
- protected int mSecondaryUserId = UserHandle.USER_OWNER;
+ protected int mSecondaryUserId = UserHandle.USER_SYSTEM;
@Override
public void setContext(Context context) {
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderPerformanceTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderPerformanceTest.java
index d581f3b..a09d5fe 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderPerformanceTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderPerformanceTest.java
@@ -47,7 +47,7 @@
// Make sure the setting changed.
String firstValue = getStringViaFrontEndApiSetting(SETTING_TYPE_GLOBAL,
- FAKE_SETTING_NAME, UserHandle.USER_OWNER);
+ FAKE_SETTING_NAME, UserHandle.USER_SYSTEM);
assertEquals("Setting value didn't change", FAKE_SETTING_VALUE, firstValue);
// Set the setting to its second value.
@@ -56,7 +56,7 @@
// Make sure the setting changed.
String secondValue = getStringViaFrontEndApiSetting(SETTING_TYPE_GLOBAL,
- FAKE_SETTING_NAME, UserHandle.USER_OWNER);
+ FAKE_SETTING_NAME, UserHandle.USER_SYSTEM);
assertEquals("Setting value didn't change", FAKE_SETTING_VALUE_1, secondValue);
}
} finally {
@@ -86,20 +86,20 @@
for (int i = 0; i < ITERATION_COUNT; i++) {
// Set the setting to its first value.
setStringViaFrontEndApiSetting(SETTING_TYPE_GLOBAL, FAKE_SETTING_NAME,
- FAKE_SETTING_VALUE, UserHandle.USER_OWNER);
+ FAKE_SETTING_VALUE, UserHandle.USER_SYSTEM);
// Make sure the setting changed.
String firstValue = getStringViaFrontEndApiSetting(SETTING_TYPE_GLOBAL,
- FAKE_SETTING_NAME, UserHandle.USER_OWNER);
+ FAKE_SETTING_NAME, UserHandle.USER_SYSTEM);
assertEquals("Setting value didn't change", FAKE_SETTING_VALUE, firstValue);
// Set the setting to its second value.
setStringViaFrontEndApiSetting(SETTING_TYPE_GLOBAL, FAKE_SETTING_NAME,
- FAKE_SETTING_VALUE_1, UserHandle.USER_OWNER);
+ FAKE_SETTING_VALUE_1, UserHandle.USER_SYSTEM);
// Make sure the setting changed.
String secondValue = getStringViaFrontEndApiSetting(SETTING_TYPE_GLOBAL,
- FAKE_SETTING_NAME, UserHandle.USER_OWNER);
+ FAKE_SETTING_NAME, UserHandle.USER_SYSTEM);
assertEquals("Setting value didn't change", FAKE_SETTING_VALUE_1, secondValue);
}
} finally {
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java
index ad56b9d..8ca1b46 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java
@@ -46,40 +46,40 @@
private final Object mLock = new Object();
- public void testSetAndGetGlobalViaFrontEndApiForOwnerUser() throws Exception {
- performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_GLOBAL, UserHandle.USER_OWNER);
+ public void testSetAndGetGlobalViaFrontEndApiForSystemUser() throws Exception {
+ performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
}
- public void testSetAndGetGlobalViaFrontEndApiForNonOwnerUser() throws Exception {
- if (mSecondaryUserId == UserHandle.USER_OWNER) {
+ public void testSetAndGetGlobalViaFrontEndApiForNonSystemUser() throws Exception {
+ if (mSecondaryUserId == UserHandle.USER_SYSTEM) {
Log.w(LOG_TAG, "No secondary user. Skipping "
- + "testSetAndGetGlobalViaFrontEndApiForNonOwnerUser");
+ + "testSetAndGetGlobalViaFrontEndApiForNonSystemUser");
return;
}
performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_GLOBAL, mSecondaryUserId);
}
- public void testSetAndGetSecureViaFrontEndApiForOwnerUser() throws Exception {
- performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SECURE, UserHandle.USER_OWNER);
+ public void testSetAndGetSecureViaFrontEndApiForSystemUser() throws Exception {
+ performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SECURE, UserHandle.USER_SYSTEM);
}
- public void testSetAndGetSecureViaFrontEndApiForNonOwnerUser() throws Exception {
- if (mSecondaryUserId == UserHandle.USER_OWNER) {
+ public void testSetAndGetSecureViaFrontEndApiForNonSystemUser() throws Exception {
+ if (mSecondaryUserId == UserHandle.USER_SYSTEM) {
Log.w(LOG_TAG, "No secondary user. Skipping "
- + "testSetAndGetSecureViaFrontEndApiForNonOwnerUser");
+ + "testSetAndGetSecureViaFrontEndApiForNonSystemUser");
return;
}
performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SECURE, mSecondaryUserId);
}
- public void testSetAndGetSystemViaFrontEndApiForOwnerUser() throws Exception {
- performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SYSTEM, UserHandle.USER_OWNER);
+ public void testSetAndGetSystemViaFrontEndApiForSystemUser() throws Exception {
+ performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SYSTEM, UserHandle.USER_SYSTEM);
}
- public void testSetAndGetSystemViaFrontEndApiForNonOwnerUser() throws Exception {
- if (mSecondaryUserId == UserHandle.USER_OWNER) {
+ public void testSetAndGetSystemViaFrontEndApiForNonSystemUser() throws Exception {
+ if (mSecondaryUserId == UserHandle.USER_SYSTEM) {
Log.w(LOG_TAG, "No secondary user. Skipping "
- + "testSetAndGetSystemViaFrontEndApiForNonOwnerUser");
+ + "testSetAndGetSystemViaFrontEndApiForNonSystemUser");
return;
}
performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SYSTEM, mSecondaryUserId);
@@ -357,7 +357,7 @@
public void run() {
insertStringViaProviderApi(type, name, value, withTableRowUri);
}
- }, type, name, value, UserHandle.USER_OWNER);
+ }, type, name, value, UserHandle.USER_SYSTEM);
}
private void setSettingAndAssertSuccessfulChange(Runnable setCommand, final int type,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 6f49fd6..0be3069 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -1051,6 +1051,7 @@
// Without this, settings is not enabled until the lock screen first appears
setShowingLocked(false);
hideLocked();
+ mUpdateMonitor.reportSuccessfulStrongAuthUnlockAttempt();
return;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
index d0a7f8a..030501b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -248,10 +248,10 @@
return STATE_FINGERPRINT_ERROR;
} else if (mUnlockMethodCache.canSkipBouncer()) {
return STATE_LOCK_OPEN;
- } else if (fingerprintRunning && unlockingAllowed) {
- return STATE_FINGERPRINT;
} else if (mUnlockMethodCache.isFaceUnlockRunning()) {
return STATE_FACE_UNLOCK;
+ } else if (fingerprintRunning && unlockingAllowed) {
+ return STATE_FINGERPRINT;
} else {
return STATE_LOCKED;
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 57769e7..7051b52 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -205,9 +205,7 @@
private final UserManager mUserManager;
- private final LockPatternUtils mLockPatternUtils;
-
- private int mCurrentUserId = UserHandle.USER_OWNER;
+ private int mCurrentUserId = UserHandle.USER_SYSTEM;
//TODO: Remove this hack
private boolean mInitialized;
@@ -230,7 +228,6 @@
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
mSecurityPolicy = new SecurityPolicy();
mMainHandler = new MainHandler(mContext.getMainLooper());
- mLockPatternUtils = new LockPatternUtils(context);
registerBroadcastReceivers();
new AccessibilityContentObserver(mMainHandler).register(
context.getContentResolver());
@@ -866,17 +863,18 @@
}
// Called only during settings restore; currently supports only the owner user
+ // TODO: http://b/22388012
void restoreEnabledAccessibilityServicesLocked(String oldSetting, String newSetting) {
readComponentNamesFromStringLocked(oldSetting, mTempComponentNameSet, false);
readComponentNamesFromStringLocked(newSetting, mTempComponentNameSet, true);
- UserState userState = getUserStateLocked(UserHandle.USER_OWNER);
+ UserState userState = getUserStateLocked(UserHandle.USER_SYSTEM);
userState.mEnabledServices.clear();
userState.mEnabledServices.addAll(mTempComponentNameSet);
persistComponentNamesToSettingLocked(
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
userState.mEnabledServices,
- UserHandle.USER_OWNER);
+ UserHandle.USER_SYSTEM);
onUserStateChangedLocked(userState);
}
@@ -1646,10 +1644,6 @@
DisplayAdjustmentUtils.applyAdjustments(mContext, userState.mUserId);
}
- private boolean hasRunningServicesLocked(UserState userState) {
- return !userState.mBoundServices.isEmpty() || !userState.mBindingServices.isEmpty();
- }
-
private MagnificationSpec getCompatibleMagnificationSpecLocked(int windowId) {
IBinder windowToken = mGlobalWindowTokens.get(windowId);
if (windowToken == null) {
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 0119000..4949138 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -2085,7 +2085,8 @@
}
private boolean collectPackageServicesLocked(String packageName, Set<String> filterByClasses,
- boolean evenPersistent, boolean doit, ArrayMap<ComponentName, ServiceRecord> services) {
+ boolean evenPersistent, boolean doit, boolean killProcess,
+ ArrayMap<ComponentName, ServiceRecord> services) {
boolean didSomething = false;
for (int i = services.size() - 1; i >= 0; i--) {
ServiceRecord service = services.valueAt(i);
@@ -2101,7 +2102,7 @@
didSomething = true;
Slog.i(TAG, " Force stopping service " + service);
if (service.app != null) {
- service.app.removed = true;
+ service.app.removed = killProcess;
if (!service.app.persistent) {
service.app.services.remove(service);
}
@@ -2118,7 +2119,7 @@
}
boolean bringDownDisabledPackageServicesLocked(String packageName, Set<String> filterByClasses,
- int userId, boolean evenPersistent, boolean doit) {
+ int userId, boolean evenPersistent, boolean killProcess, boolean doit) {
boolean didSomething = false;
if (mTmpCollectionResults != null) {
@@ -2128,7 +2129,7 @@
if (userId == UserHandle.USER_ALL) {
for (int i = mServiceMap.size() - 1; i >= 0; i--) {
didSomething |= collectPackageServicesLocked(packageName, filterByClasses,
- evenPersistent, doit, mServiceMap.valueAt(i).mServicesByName);
+ evenPersistent, doit, killProcess, mServiceMap.valueAt(i).mServicesByName);
if (!doit && didSomething) {
return true;
}
@@ -2138,7 +2139,7 @@
if (smap != null) {
ArrayMap<ComponentName, ServiceRecord> items = smap.mServicesByName;
didSomething = collectPackageServicesLocked(packageName, filterByClasses,
- evenPersistent, doit, items);
+ evenPersistent, doit, killProcess, items);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 3554c39..830dced 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -5647,7 +5647,7 @@
}
private void cleanupDisabledPackageComponentsLocked(
- String packageName, int userId, String[] changedClasses) {
+ String packageName, int userId, boolean killProcess, String[] changedClasses) {
Set<String> disabledClasses = null;
boolean packageDisabled = false;
@@ -5717,7 +5717,7 @@
// Clean-up disabled services.
mServices.bringDownDisabledPackageServicesLocked(
- packageName, disabledClasses, userId, false, true);
+ packageName, disabledClasses, userId, false, killProcess, true);
// Clean-up disabled providers.
ArrayList<ContentProviderRecord> providers = new ArrayList<>();
@@ -5802,7 +5802,7 @@
}
if (mServices.bringDownDisabledPackageServicesLocked(
- packageName, null, userId, evenPersistent, doit)) {
+ packageName, null, userId, evenPersistent, true, doit)) {
if (!doit) {
return true;
}
@@ -16892,7 +16892,9 @@
boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
boolean fullUninstall = removed &&
!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
- if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
+ final boolean killProcess =
+ !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
+ if (killProcess) {
forceStopPackageLocked(ssp, UserHandle.getAppId(
intent.getIntExtra(Intent.EXTRA_UID, -1)),
false, true, true, false, fullUninstall, userId,
@@ -16912,7 +16914,7 @@
mBatteryStatsService.notePackageUninstalled(ssp);
}
} else {
- cleanupDisabledPackageComponentsLocked(ssp, userId,
+ cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
intent.getStringArrayExtra(
Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
}
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 67c9ee8..0023258 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -259,7 +259,7 @@
}
private boolean inLockoutMode() {
- return mFailedAttempts > MAX_FAILED_ATTEMPTS;
+ return mFailedAttempts >= MAX_FAILED_ATTEMPTS;
}
private void resetFailedAttempts() {
@@ -275,7 +275,7 @@
private boolean handleFailedAttempt(ClientMonitor clientMonitor) {
mFailedAttempts++;
- if (mFailedAttempts > MAX_FAILED_ATTEMPTS) {
+ if (inLockoutMode()) {
// Failing multiple times will continue to push out the lockout time.
mHandler.removeCallbacks(mLockoutReset);
mHandler.postDelayed(mLockoutReset, FAIL_LOCKOUT_TIMEOUT_MS);
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 17b4f9c..5a13672 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -17,6 +17,7 @@
package com.android.server.input;
import android.view.Display;
+import com.android.internal.os.SomeArgs;
import com.android.internal.R;
import com.android.internal.util.XmlUtils;
import com.android.server.DisplayThread;
@@ -52,6 +53,7 @@
import android.hardware.input.InputDeviceIdentifier;
import android.hardware.input.InputManager;
import android.hardware.input.InputManagerInternal;
+import android.hardware.input.ITabletModeChangedListener;
import android.hardware.input.KeyboardLayout;
import android.hardware.input.TouchCalibration;
import android.os.Binder;
@@ -93,6 +95,7 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import libcore.io.Streams;
import libcore.util.Objects;
@@ -112,6 +115,7 @@
private static final int MSG_RELOAD_KEYBOARD_LAYOUTS = 3;
private static final int MSG_UPDATE_KEYBOARD_LAYOUTS = 4;
private static final int MSG_RELOAD_DEVICE_ALIASES = 5;
+ private static final int MSG_DELIVER_TABLET_MODE_CHANGED = 6;
// Pointer to native input manager service object.
private final long mPtr;
@@ -124,6 +128,13 @@
private boolean mSystemReady;
private NotificationManager mNotificationManager;
+ private final Object mTabletModeLock = new Object();
+ // List of currently registered tablet mode changed listeners by process id
+ private final SparseArray<TabletModeChangedListenerRecord> mTabletModeChangedListeners =
+ new SparseArray<>(); // guarded by mTabletModeLock
+ private final List<TabletModeChangedListenerRecord> mTempTabletModeChangedListenersToNotify =
+ new ArrayList<>();
+
// Persistent data store. Must be locked each time during use.
private final PersistentDataStore mDataStore = new PersistentDataStore();
@@ -227,6 +238,11 @@
/** Switch code: Lid switch. When set, lid is shut. */
public static final int SW_LID = 0x00;
+ /** Switch code: Tablet mode switch.
+ * When set, the device is in tablet mode (i.e. no keyboard is connected).
+ */
+ public static final int SW_TABLET_MODE = 0x01;
+
/** Switch code: Keypad slide. When set, keyboard is exposed. */
public static final int SW_KEYPAD_SLIDE = 0x0a;
@@ -246,6 +262,7 @@
public static final int SW_CAMERA_LENS_COVER = 0x09;
public static final int SW_LID_BIT = 1 << SW_LID;
+ public static final int SW_TABLET_MODE_BIT = 1 << SW_TABLET_MODE;
public static final int SW_KEYPAD_SLIDE_BIT = 1 << SW_KEYPAD_SLIDE;
public static final int SW_HEADPHONE_INSERT_BIT = 1 << SW_HEADPHONE_INSERT;
public static final int SW_MICROPHONE_INSERT_BIT = 1 << SW_MICROPHONE_INSERT;
@@ -774,6 +791,57 @@
}
}
+ @Override // Binder call
+ public void registerTabletModeChangedListener(ITabletModeChangedListener listener) {
+ if (!checkCallingPermission(android.Manifest.permission.TABLET_MODE_LISTENER,
+ "registerTabletModeChangedListener()")) {
+ throw new SecurityException("Requires TABLET_MODE_LISTENER permission");
+ }
+ if (listener == null) {
+ throw new IllegalArgumentException("listener must not be null");
+ }
+
+ synchronized (mTabletModeLock) {
+ final int callingPid = Binder.getCallingPid();
+ if (mTabletModeChangedListeners.get(callingPid) != null) {
+ throw new IllegalStateException("The calling process has already registered "
+ + "a TabletModeChangedListener.");
+ }
+ TabletModeChangedListenerRecord record =
+ new TabletModeChangedListenerRecord(callingPid, listener);
+ try {
+ IBinder binder = listener.asBinder();
+ binder.linkToDeath(record, 0);
+ } catch (RemoteException ex) {
+ throw new RuntimeException(ex);
+ }
+ mTabletModeChangedListeners.put(callingPid, record);
+ }
+ }
+
+ private void onTabletModeChangedListenerDied(int pid) {
+ synchronized (mTabletModeLock) {
+ mTabletModeChangedListeners.remove(pid);
+ }
+ }
+
+ // Must be called on handler
+ private void deliverTabletModeChanged(long whenNanos, boolean inTabletMode) {
+ mTempTabletModeChangedListenersToNotify.clear();
+ final int numListeners;
+ synchronized (mTabletModeLock) {
+ numListeners = mTabletModeChangedListeners.size();
+ for (int i = 0; i < numListeners; i++) {
+ mTempTabletModeChangedListenersToNotify.add(
+ mTabletModeChangedListeners.valueAt(i));
+ }
+ }
+ for (int i = 0; i < numListeners; i++) {
+ mTempTabletModeChangedListenersToNotify.get(i).notifyTabletModeChanged(
+ whenNanos, inTabletMode);
+ }
+ }
+
// Must be called on handler.
private void showMissingKeyboardLayoutNotification(InputDevice device) {
if (!mKeyboardLayoutNotificationShown) {
@@ -1419,6 +1487,15 @@
mWiredAccessoryCallbacks.notifyWiredAccessoryChanged(whenNanos, switchValues,
switchMask);
}
+
+ if ((switchMask & SW_TABLET_MODE) != 0) {
+ SomeArgs args = SomeArgs.obtain();
+ args.argi1 = (int) (whenNanos & 0xFFFFFFFF);
+ args.argi2 = (int) (whenNanos >> 32);
+ args.arg1 = Boolean.valueOf((switchValues & SW_TABLET_MODE_BIT) != 0);
+ mHandler.obtainMessage(MSG_DELIVER_TABLET_MODE_CHANGED,
+ args).sendToTarget();
+ }
}
// Native callback.
@@ -1664,6 +1741,12 @@
case MSG_RELOAD_DEVICE_ALIASES:
reloadDeviceAliases();
break;
+ case MSG_DELIVER_TABLET_MODE_CHANGED:
+ SomeArgs args = (SomeArgs) msg.obj;
+ long whenNanos = (args.argi1 & 0xFFFFFFFFl) | ((long) args.argi2 << 32);
+ boolean inTabletMode = (boolean) args.arg1;
+ deliverTabletModeChanged(whenNanos, inTabletMode);
+ break;
}
}
}
@@ -1755,6 +1838,34 @@
}
}
+ private final class TabletModeChangedListenerRecord implements DeathRecipient {
+ private final int mPid;
+ private final ITabletModeChangedListener mListener;
+
+ public TabletModeChangedListenerRecord(int pid, ITabletModeChangedListener listener) {
+ mPid = pid;
+ mListener = listener;
+ }
+
+ @Override
+ public void binderDied() {
+ if (DEBUG) {
+ Slog.d(TAG, "Tablet mode changed listener for pid " + mPid + " died.");
+ }
+ onTabletModeChangedListenerDied(mPid);
+ }
+
+ public void notifyTabletModeChanged(long whenNanos, boolean inTabletMode) {
+ try {
+ mListener.onTabletModeChanged(whenNanos, inTabletMode);
+ } catch (RemoteException ex) {
+ Slog.w(TAG, "Failed to notify process " + mPid +
+ " that tablet mode changed, assuming it died.", ex);
+ binderDied();
+ }
+ }
+ }
+
private final class VibratorToken implements DeathRecipient {
public final int mDeviceId;
public final IBinder mToken;
diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java
index 239c471..5e5a55c 100644
--- a/services/core/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/core/java/com/android/server/location/GpsLocationProvider.java
@@ -447,7 +447,8 @@
checkSmsSuplInit(intent);
} else if (action.equals(Intents.WAP_PUSH_RECEIVED_ACTION)) {
checkWapSuplInit(intent);
- } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
+ } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)
+ || action.equals(ConnectivityManager.CONNECTIVITY_ACTION_SUPL)) {
// retrieve NetworkType result for this UID
int networkType = intent.getIntExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, -1);
if (DEBUG) Log.d(TAG, "Connectivity action, type=" + networkType);
@@ -2067,6 +2068,7 @@
intentFilter.addAction(ALARM_WAKEUP);
intentFilter.addAction(ALARM_TIMEOUT);
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+ intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION_SUPL);
intentFilter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
intentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 88088fa..82afdd7 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -5999,12 +5999,6 @@
*/
if (shouldHideSystemApp) {
synchronized (mPackages) {
- /*
- * We have to grant systems permissions before we hide, because
- * grantPermissions will assume the package update is trying to
- * expand its permissions.
- */
- grantPermissionsLPw(pkg, true, pkg.packageName);
mSettings.disableSystemPackageLPw(pkg.packageName);
}
}
diff --git a/services/net/java/android/net/dhcp/DhcpPacket.java b/services/net/java/android/net/dhcp/DhcpPacket.java
index a91ddb8..cbf8fc2 100644
--- a/services/net/java/android/net/dhcp/DhcpPacket.java
+++ b/services/net/java/android/net/dhcp/DhcpPacket.java
@@ -55,6 +55,7 @@
public static final int MIN_PACKET_LENGTH_L3 = MIN_PACKET_LENGTH_BOOTP + 20 + 8;
public static final int MIN_PACKET_LENGTH_L2 = MIN_PACKET_LENGTH_L3 + 14;
+ public static final int HWADDR_LEN = 16;
public static final int MAX_OPTION_LEN = 255;
/**
* IP layer definitions.
@@ -399,7 +400,7 @@
buf.put(mRelayIp.getAddress());
buf.put(mClientMac);
buf.position(buf.position() +
- (16 - mClientMac.length) // pad addr to 16 bytes
+ (HWADDR_LEN - mClientMac.length) // pad addr to 16 bytes
+ 64 // empty server host name (64 bytes)
+ 128); // empty boot file name (128 bytes)
buf.putInt(0x63825363); // magic number
@@ -786,7 +787,7 @@
byte type = packet.get();
byte hwType = packet.get();
- byte addrLen = packet.get();
+ int addrLen = packet.get() & 0xff;
byte hops = packet.get();
transactionId = packet.getInt();
secs = packet.getShort();
@@ -807,6 +808,16 @@
return null;
}
+ // Some DHCP servers have been known to announce invalid client hardware address values such
+ // as 0xff. The legacy DHCP client accepted these becuause it does not check the length at
+ // all but only checks that the interface MAC address matches the first bytes of the address
+ // in the packets. We're a bit stricter: if the length is obviously invalid (i.e., bigger
+ // than the size of the field), we fudge it to 6 (Ethernet). http://b/23725795
+ // TODO: evaluate whether to make this test more liberal.
+ if (addrLen > HWADDR_LEN) {
+ addrLen = ETHER_BROADCAST.length;
+ }
+
clientMac = new byte[addrLen];
packet.get(clientMac);
diff --git a/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java b/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java
index da1df1a..cd3b8bb 100644
--- a/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java
+++ b/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java
@@ -333,6 +333,76 @@
}
@SmallTest
+ public void testBadHwaddrLength() throws Exception {
+ final ByteBuffer packet = ByteBuffer.wrap(HexEncoding.decode((
+ // IP header.
+ "450001518d0600004011144dc0a82b01c0a82bf7" +
+ // UDP header.
+ "00430044013d9ac7" +
+ // BOOTP header.
+ "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
+ // MAC address.
+ "30766ff2a90c00000000000000000000" +
+ // Server name.
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ // File.
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ // Options
+ "638253633501023604c0a82b01330400000e103a04000007083b0400000c4e0104ffffff00" +
+ "1c04c0a82bff0304c0a82b010604c0a82b012b0f414e44524f49445f4d455445524544ff"
+ ).toCharArray(), false));
+ String expectedClientMac = "30766FF2A90C";
+
+ final int hwAddrLenOffset = 20 + 8 + 2;
+ assertEquals(6, packet.get(hwAddrLenOffset));
+
+ // Expect the expected.
+ DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
+ assertNotNull(offerPacket);
+ assertEquals(6, offerPacket.getClientMac().length);
+ assertEquals(expectedClientMac, HexDump.toHexString(offerPacket.getClientMac()));
+
+ // Reduce the hardware address length and verify that it shortens the client MAC.
+ packet.flip();
+ packet.put(hwAddrLenOffset, (byte) 5);
+ offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
+ assertNotNull(offerPacket);
+ assertEquals(5, offerPacket.getClientMac().length);
+ assertEquals(expectedClientMac.substring(0, 10),
+ HexDump.toHexString(offerPacket.getClientMac()));
+
+ packet.flip();
+ packet.put(hwAddrLenOffset, (byte) 3);
+ offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
+ assertNotNull(offerPacket);
+ assertEquals(3, offerPacket.getClientMac().length);
+ assertEquals(expectedClientMac.substring(0, 6),
+ HexDump.toHexString(offerPacket.getClientMac()));
+
+ // Set the the hardware address length to 0xff and verify that we a) don't treat it as -1
+ // and crash, and b) hardcode it to 6.
+ packet.flip();
+ packet.put(hwAddrLenOffset, (byte) -1);
+ offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
+ assertNotNull(offerPacket);
+ assertEquals(6, offerPacket.getClientMac().length);
+ assertEquals(expectedClientMac, HexDump.toHexString(offerPacket.getClientMac()));
+
+ // Set the the hardware address length to a positive invalid value (> 16) and verify that we
+ // hardcode it to 6.
+ packet.flip();
+ packet.put(hwAddrLenOffset, (byte) 17);
+ offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
+ assertNotNull(offerPacket);
+ assertEquals(6, offerPacket.getClientMac().length);
+ assertEquals(expectedClientMac, HexDump.toHexString(offerPacket.getClientMac()));
+ }
+
+ @SmallTest
public void testPadAndOverloadedOptionsOffer() throws Exception {
// A packet observed in the real world that is interesting for two reasons:
//
diff --git a/services/tests/servicestests/src/com/android/server/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/AccessibilityManagerServiceTest.java
index fd9fc98..51e14d3 100644
--- a/services/tests/servicestests/src/com/android/server/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/AccessibilityManagerServiceTest.java
@@ -54,7 +54,7 @@
* Timeout in which we are waiting for the system to start the mock
* accessibility services.
*/
- private static final long TIMEOUT_START_MOCK_ACCESSIBILITY_SERVICES = 300;
+ private static final long TIMEOUT_START_MOCK_ACCESSIBILITY_SERVICES = 1000;
/**
* Timeout used for testing that a service is notified only upon a
@@ -68,6 +68,12 @@
private IAccessibilityManager mManagerService;
@Override
+ protected void setUp() throws Exception {
+ // Reset the state.
+ ensureOnlyMockServicesEnabled(getContext(), false, false);
+ }
+
+ @Override
public void setContext(Context context) {
super.setContext(context);
if (MyFirstMockAccessibilityService.sComponentName == null) {
@@ -92,6 +98,9 @@
@LargeTest
public void testAddClient_AccessibilityDisabledThenEnabled() throws Exception {
+ // at least some service must be enabled, otherwise accessibility will always be disabled.
+ ensureOnlyMockServicesEnabled(mContext, true, false);
+
// make sure accessibility is disabled
ensureAccessibilityEnabled(mContext, false);
@@ -99,7 +108,8 @@
MyMockAccessibilityManagerClient mockClient = new MyMockAccessibilityManagerClient();
// invoke the method under test
- final int stateFlagsDisabled = mManagerService.addClient(mockClient, UserHandle.USER_OWNER);
+ final int stateFlagsDisabled =
+ mManagerService.addClient(mockClient, UserHandle.USER_CURRENT);
boolean enabledAccessibilityDisabled =
(stateFlagsDisabled & AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED) != 0;
@@ -111,11 +121,11 @@
ensureAccessibilityEnabled(mContext, true);
// invoke the method under test
- final int stateFlagsEnabled = mManagerService.addClient(mockClient, UserHandle.USER_OWNER);
+ final int stateFlagsEnabled =
+ mManagerService.addClient(mockClient, UserHandle.USER_CURRENT);
boolean enabledAccessibilityEnabled =
(stateFlagsEnabled & AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED) != 0;
-
// check expected result
assertTrue("The client must be enabled since accessibility is enabled.",
enabledAccessibilityEnabled);
@@ -123,6 +133,9 @@
@LargeTest
public void testAddClient_AccessibilityEnabledThenDisabled() throws Exception {
+ // at least some service must be enabled, otherwise accessibility will always be disabled.
+ ensureOnlyMockServicesEnabled(mContext, true, false);
+
// enable accessibility before registering the client
ensureAccessibilityEnabled(mContext, true);
@@ -130,7 +143,8 @@
MyMockAccessibilityManagerClient mockClient = new MyMockAccessibilityManagerClient();
// invoke the method under test
- final int stateFlagsEnabled = mManagerService.addClient(mockClient, UserHandle.USER_OWNER);
+ final int stateFlagsEnabled =
+ mManagerService.addClient(mockClient, UserHandle.USER_CURRENT);
boolean enabledAccessibilityEnabled =
(stateFlagsEnabled & AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED) != 0;
@@ -142,7 +156,8 @@
ensureAccessibilityEnabled(mContext, false);
// invoke the method under test
- final int stateFlagsDisabled = mManagerService.addClient(mockClient, UserHandle.USER_OWNER);
+ final int stateFlagsDisabled =
+ mManagerService.addClient(mockClient, UserHandle.USER_CURRENT);
boolean enabledAccessibilityDisabled =
(stateFlagsDisabled & AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED) != 0;
@@ -162,7 +177,7 @@
// look for the two mock services
for (AccessibilityServiceInfo info : mManagerService.getInstalledAccessibilityServiceList(
- UserHandle.USER_OWNER)) {
+ UserHandle.USER_CURRENT)) {
ServiceInfo serviceInfo = info.getResolveInfo().serviceInfo;
if (packageName.equals(serviceInfo.packageName)) {
if (firstMockServiceClassName.equals(serviceInfo.name)) {
@@ -181,12 +196,12 @@
@LargeTest
public void testSendAccessibilityEvent_OneService_MatchingPackageAndEventType()
throws Exception {
- // set the accessibility setting value
- ensureAccessibilityEnabled(mContext, true);
-
// enable the mock accessibility service
ensureOnlyMockServicesEnabled(mContext, true, false);
+ // set the accessibility setting value
+ ensureAccessibilityEnabled(mContext, true);
+
// configure the mock service
MockAccessibilityService service = MyFirstMockAccessibilityService.sInstance;
service.setServiceInfo(MockAccessibilityService.createDefaultInfo());
@@ -203,7 +218,7 @@
service.replay();
// send the event
- mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_OWNER);
+ mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_CURRENT);
// verify if all expected methods have been called
assertMockServiceVerifiedWithinTimeout(service);
@@ -211,12 +226,12 @@
@LargeTest
public void testSendAccessibilityEvent_OneService_NotMatchingPackage() throws Exception {
- // set the accessibility setting value
- ensureAccessibilityEnabled(mContext, true);
-
// enable the mock accessibility service
ensureOnlyMockServicesEnabled(mContext, true, false);
+ // set the accessibility setting value
+ ensureAccessibilityEnabled(mContext, true);
+
// configure the mock service
MockAccessibilityService service = MyFirstMockAccessibilityService.sInstance;
service.setServiceInfo(MockAccessibilityService.createDefaultInfo());
@@ -233,7 +248,7 @@
service.replay();
// send the event
- mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_OWNER);
+ mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_CURRENT);
// verify if all expected methods have been called
assertMockServiceVerifiedWithinTimeout(service);
@@ -241,12 +256,12 @@
@LargeTest
public void testSendAccessibilityEvent_OneService_NotMatchingEventType() throws Exception {
- // set the accessibility setting value
- ensureAccessibilityEnabled(mContext, true);
-
// enable the mock accessibility service
ensureOnlyMockServicesEnabled(mContext, true, false);
+ // set the accessibility setting value
+ ensureAccessibilityEnabled(mContext, true);
+
// configure the mock service
MockAccessibilityService service = MyFirstMockAccessibilityService.sInstance;
service.setServiceInfo(MockAccessibilityService.createDefaultInfo());
@@ -263,7 +278,7 @@
service.replay();
// send the event
- mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_OWNER);
+ mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_CURRENT);
// verify if all expected methods have been called
assertMockServiceVerifiedWithinTimeout(service);
@@ -271,12 +286,12 @@
@LargeTest
public void testSendAccessibilityEvent_OneService_NotifivationAfterTimeout() throws Exception {
- // set the accessibility setting value
- ensureAccessibilityEnabled(mContext, true);
-
// enable the mock accessibility service
ensureOnlyMockServicesEnabled(mContext, true, false);
+ // set the accessibility setting value
+ ensureAccessibilityEnabled(mContext, true);
+
// configure the mock service
MockAccessibilityService service = MyFirstMockAccessibilityService.sInstance;
AccessibilityServiceInfo info = MockAccessibilityService.createDefaultInfo();
@@ -299,8 +314,8 @@
service.replay();
// send the events
- mManagerService.sendAccessibilityEvent(firstEvent, UserHandle.USER_OWNER);
- mManagerService.sendAccessibilityEvent(secondEvent, UserHandle.USER_OWNER);
+ mManagerService.sendAccessibilityEvent(firstEvent, UserHandle.USER_CURRENT);
+ mManagerService.sendAccessibilityEvent(secondEvent, UserHandle.USER_CURRENT);
// wait for #sendAccessibilityEvent to reach the backing service
Thread.sleep(TIMEOUT_BINDER_CALL);
@@ -322,12 +337,12 @@
@LargeTest
public void testSendAccessibilityEvent_TwoServices_MatchingPackageAndEventType_DiffFeedback()
throws Exception {
- // set the accessibility setting value
- ensureAccessibilityEnabled(mContext, true);
-
// enable the mock accessibility services
ensureOnlyMockServicesEnabled(mContext, true, true);
+ // set the accessibility setting value
+ ensureAccessibilityEnabled(mContext, true);
+
// configure the first mock service
MockAccessibilityService firstService = MyFirstMockAccessibilityService.sInstance;
AccessibilityServiceInfo firstInfo = MockAccessibilityService.createDefaultInfo();
@@ -356,7 +371,7 @@
secondService.replay();
// send the event
- mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_OWNER);
+ mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_CURRENT);
// verify if all expected methods have been called
assertMockServiceVerifiedWithinTimeout(firstService);
@@ -366,12 +381,12 @@
@LargeTest
public void testSendAccessibilityEvent_TwoServices_MatchingPackageAndEventType()
throws Exception {
- // set the accessibility setting value
- ensureAccessibilityEnabled(mContext, true);
-
// enable the mock accessibility services
ensureOnlyMockServicesEnabled(mContext, true, true);
+ // set the accessibility setting value
+ ensureAccessibilityEnabled(mContext, true);
+
// configure the first mock service
MockAccessibilityService firstService = MyFirstMockAccessibilityService.sInstance;
firstService.setServiceInfo(MockAccessibilityService.createDefaultInfo());
@@ -395,7 +410,7 @@
secondService.replay();
// send the event
- mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_OWNER);
+ mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_CURRENT);
// verify if all expected methods have been called
assertMockServiceVerifiedWithinTimeout(firstService);
@@ -405,12 +420,12 @@
@LargeTest
public void testSendAccessibilityEvent_TwoServices_MatchingPackageAndEventType_OneDefault()
throws Exception {
- // set the accessibility setting value
- ensureAccessibilityEnabled(mContext, true);
-
// enable the mock accessibility services
ensureOnlyMockServicesEnabled(mContext, true, true);
+ // set the accessibility setting value
+ ensureAccessibilityEnabled(mContext, true);
+
// configure the first mock service
MockAccessibilityService firstService = MyFirstMockAccessibilityService.sInstance;
AccessibilityServiceInfo firstInfo = MyFirstMockAccessibilityService.createDefaultInfo();
@@ -436,7 +451,7 @@
secondService.replay();
// send the event
- mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_OWNER);
+ mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_CURRENT);
// verify if all expected methods have been called
assertMockServiceVerifiedWithinTimeout(firstService);
@@ -446,12 +461,12 @@
@LargeTest
public void testSendAccessibilityEvent_TwoServices_MatchingPackageAndEventType_TwoDefault()
throws Exception {
- // set the accessibility setting value
- ensureAccessibilityEnabled(mContext, true);
-
// enable the mock accessibility services
ensureOnlyMockServicesEnabled(mContext, true, true);
+ // set the accessibility setting value
+ ensureAccessibilityEnabled(mContext, true);
+
// configure the first mock service
MockAccessibilityService firstService = MyFirstMockAccessibilityService.sInstance;
AccessibilityServiceInfo firstInfo = MyFirstMockAccessibilityService.createDefaultInfo();
@@ -479,7 +494,7 @@
secondService.replay();
// send the event
- mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_OWNER);
+ mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_CURRENT);
// verify if all expected methods have been called
assertMockServiceVerifiedWithinTimeout(firstService);
@@ -488,12 +503,12 @@
@LargeTest
public void testInterrupt() throws Exception {
- // set the accessibility setting value
- ensureAccessibilityEnabled(mContext, true);
-
// enable the mock accessibility services
ensureOnlyMockServicesEnabled(mContext, true, true);
+ // set the accessibility setting value
+ ensureAccessibilityEnabled(mContext, true);
+
// configure the first mock service
MockAccessibilityService firstService = MyFirstMockAccessibilityService.sInstance;
firstService.setServiceInfo(MockAccessibilityService.createDefaultInfo());
@@ -514,7 +529,7 @@
secondService.replay();
// call the method under test
- mManagerService.interrupt(UserHandle.USER_OWNER);
+ mManagerService.interrupt(UserHandle.USER_CURRENT);
// verify if all expected methods have been called
assertMockServiceVerifiedWithinTimeout(firstService);
@@ -534,7 +549,7 @@
sentEvent.setContentDescription("ContentDescription");
sentEvent.setCurrentItemIndex(1);
sentEvent.setEnabled(true);
- sentEvent.setEventType(AccessibilityEvent.TYPE_VIEW_CLICKED);
+ sentEvent.setEventType(AccessibilityEvent.TYPE_ANNOUNCEMENT);
sentEvent.setEventTime(1000);
sentEvent.setFromIndex(1);
sentEvent.setFullScreen(true);
@@ -568,8 +583,8 @@
* @throws Exception If any error occurs.
*/
private void ensureAccessibilityEnabled(Context context, boolean enabled) throws Exception {
- boolean isEnabled = (Settings.Secure.getInt(context.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1 ? true : false);
+ boolean isEnabled = Settings.Secure.getInt(context.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1;
if (isEnabled == enabled) {
return;
@@ -608,13 +623,14 @@
servicesToEnable.append(MySecondMockAccessibilityService.sComponentName).append(":");
}
+ Settings.Secure.putString(context.getContentResolver(),
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, servicesToEnable.toString());
+
+ // Optimization. If things will not change, we don't have to do anything.
if (servicesToEnable.equals(enabledServices)) {
return;
}
- Settings.Secure.putString(context.getContentResolver(),
- Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, servicesToEnable.toString());
-
// we have enabled the services of interest and need to wait until they
// are instantiated and started (if needed) and the system binds to them
boolean firstMockServiceOK = false;
@@ -664,13 +680,13 @@
throws Exception {
Exception lastVerifyException = null;
long beginTime = SystemClock.uptimeMillis();
- long pollTmeout = TIMEOUT_BINDER_CALL / 5;
+ long pollTimeout = TIMEOUT_BINDER_CALL / 5;
// poll until the timeout has elapsed
while (SystemClock.uptimeMillis() - beginTime < TIMEOUT_BINDER_CALL) {
// sleep first since immediate call will always fail
try {
- Thread.sleep(pollTmeout);
+ Thread.sleep(pollTimeout);
} catch (InterruptedException ie) {
/* ignore */
}
diff --git a/services/tests/servicestests/src/com/android/server/AccessibilityManagerTest.java b/services/tests/servicestests/src/com/android/server/AccessibilityManagerTest.java
index e7366ea..026a2ad 100644
--- a/services/tests/servicestests/src/com/android/server/AccessibilityManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/AccessibilityManagerTest.java
@@ -16,14 +16,11 @@
package com.android.server;
-import static org.easymock.EasyMock.createStrictMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.reportMatcher;
-import static org.easymock.EasyMock.reset;
-import static org.easymock.EasyMock.verify;
-
-import org.easymock.IArgumentMatcher;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.os.UserHandle;
@@ -35,6 +32,9 @@
import android.view.accessibility.IAccessibilityManager;
import android.view.accessibility.IAccessibilityManagerClient;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
import java.util.ArrayList;
import java.util.List;
@@ -49,78 +49,65 @@
*/
public static final long TIMEOUT_BINDER_CALL = 50;
- /**
- * The reusable mock {@link IAccessibilityManager}.
- */
- private final IAccessibilityManager mMockServiceInterface =
- createStrictMock(IAccessibilityManager.class);
+ @Mock
+ private IAccessibilityManager mMockService;
@Override
public void setUp() throws Exception {
- reset(mMockServiceInterface);
+ MockitoAnnotations.initMocks(this);
+ }
+
+ private AccessibilityManager createManager(boolean enabled) throws Exception {
+ if (enabled) {
+ when(mMockService.addClient(any(IAccessibilityManagerClient.class), anyInt()))
+ .thenReturn(AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED);
+ } else {
+ when(mMockService.addClient(any(IAccessibilityManagerClient.class), anyInt()))
+ .thenReturn(0);
+ }
+
+ AccessibilityManager manager =
+ new AccessibilityManager(mContext, mMockService, UserHandle.USER_CURRENT);
+
+ verify(mMockService).addClient(any(IAccessibilityManagerClient.class), anyInt());
+
+ return manager;
}
@MediumTest
public void testGetAccessibilityServiceList() throws Exception {
// create a list of installed accessibility services the mock service returns
- List<AccessibilityServiceInfo> expectedServices = new ArrayList<AccessibilityServiceInfo>();
+ List<AccessibilityServiceInfo> expectedServices = new ArrayList<>();
AccessibilityServiceInfo accessibilityServiceInfo = new AccessibilityServiceInfo();
accessibilityServiceInfo.packageNames = new String[] { "foo.bar" };
expectedServices.add(accessibilityServiceInfo);
// configure the mock service behavior
- IAccessibilityManager mockServiceInterface = mMockServiceInterface;
- expect(mockServiceInterface.addClient(anyIAccessibilityManagerClient(),
- UserHandle.USER_OWNER)).andReturn(
- AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED);
- expect(mockServiceInterface.getInstalledAccessibilityServiceList(UserHandle.USER_OWNER))
- .andReturn(expectedServices);
- replay(mockServiceInterface);
+ when(mMockService.getInstalledAccessibilityServiceList(anyInt()))
+ .thenReturn(expectedServices);
// invoke the method under test
- AccessibilityManager manager = new AccessibilityManager(mContext, mockServiceInterface,
- UserHandle.USER_OWNER);
+ AccessibilityManager manager = createManager(true);
List<AccessibilityServiceInfo> receivedServices =
- manager.getInstalledAccessibilityServiceList();
+ manager.getInstalledAccessibilityServiceList();
+ verify(mMockService).getInstalledAccessibilityServiceList(UserHandle.USER_CURRENT);
// check expected result (list equals() compares it contents as well)
- assertEquals("All expected services must be returned", receivedServices, expectedServices);
-
- // verify the mock service was properly called
- verify(mockServiceInterface);
+ assertEquals("All expected services must be returned", expectedServices, receivedServices);
}
@MediumTest
public void testInterrupt() throws Exception {
- // configure the mock service behavior
- IAccessibilityManager mockServiceInterface = mMockServiceInterface;
- expect(mockServiceInterface.addClient(anyIAccessibilityManagerClient(),
- UserHandle.USER_OWNER)).andReturn(
- AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED);
- mockServiceInterface.interrupt(UserHandle.USER_OWNER);
- replay(mockServiceInterface);
-
- // invoke the method under test
- AccessibilityManager manager = new AccessibilityManager(mContext, mockServiceInterface,
- UserHandle.USER_OWNER);
+ AccessibilityManager manager = createManager(true);
manager.interrupt();
- // verify the mock service was properly called
- verify(mockServiceInterface);
+ verify(mMockService).interrupt(UserHandle.USER_CURRENT);
}
@LargeTest
public void testIsEnabled() throws Exception {
- // configure the mock service behavior
- IAccessibilityManager mockServiceInterface = mMockServiceInterface;
- expect(mockServiceInterface.addClient(anyIAccessibilityManagerClient(),
- UserHandle.USER_OWNER)).andReturn(
- AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED);
- replay(mockServiceInterface);
-
// invoke the method under test
- AccessibilityManager manager = new AccessibilityManager(mContext, mockServiceInterface,
- UserHandle.USER_OWNER);
+ AccessibilityManager manager = createManager(true);
boolean isEnabledServiceEnabled = manager.isEnabled();
// check expected result
@@ -138,63 +125,32 @@
// check expected result
assertFalse("Must be disabled since the mock service is disabled",
isEnabledServcieDisabled);
-
- // verify the mock service was properly called
- verify(mockServiceInterface);
}
@MediumTest
public void testSendAccessibilityEvent_AccessibilityEnabled() throws Exception {
- // create an event to be dispatched
AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
- // configure the mock service behavior
- IAccessibilityManager mockServiceInterface = mMockServiceInterface;
- expect(mockServiceInterface.addClient(anyIAccessibilityManagerClient(),
- UserHandle.USER_OWNER)).andReturn(
- AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED);
- expect(mockServiceInterface.sendAccessibilityEvent(eqAccessibilityEvent(sentEvent),
- UserHandle.USER_OWNER)).andReturn(true);
- expect(mockServiceInterface.sendAccessibilityEvent(eqAccessibilityEvent(sentEvent),
- UserHandle.USER_OWNER)).andReturn(false);
- replay(mockServiceInterface);
+ when(mMockService.sendAccessibilityEvent(eq(sentEvent), anyInt()))
+ .thenReturn(true /* should recycle event object */)
+ .thenReturn(false /* should not recycle event object */);
- // invoke the method under test (manager and service in different processes)
- AccessibilityManager manager = new AccessibilityManager(mContext, mockServiceInterface,
- UserHandle.USER_OWNER);
+ AccessibilityManager manager = createManager(true);
manager.sendAccessibilityEvent(sentEvent);
- // check expected result
- AccessibilityEvent nextEventDifferentProcesses = AccessibilityEvent.obtain();
- assertSame("The manager and the service are in different processes, so the event must be " +
- "recycled", sentEvent, nextEventDifferentProcesses);
+ assertSame("The event should be recycled.", sentEvent, AccessibilityEvent.obtain());
- // invoke the method under test (manager and service in the same process)
manager.sendAccessibilityEvent(sentEvent);
- // check expected result
- AccessibilityEvent nextEventSameProcess = AccessibilityEvent.obtain();
- assertNotSame("The manager and the service are in the same process, so the event must not" +
- "be recycled", sentEvent, nextEventSameProcess);
-
- // verify the mock service was properly called
- verify(mockServiceInterface);
+ assertNotSame("The event should not be recycled.", sentEvent, AccessibilityEvent.obtain());
}
@MediumTest
public void testSendAccessibilityEvent_AccessibilityDisabled() throws Exception {
- // create an event to be dispatched
AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
- // configure the mock service behavior
- IAccessibilityManager mockServiceInterface = mMockServiceInterface;
- expect(mockServiceInterface.addClient(anyIAccessibilityManagerClient(),
- UserHandle.USER_OWNER)).andReturn(0);
- replay(mockServiceInterface);
+ AccessibilityManager manager = createManager(false /* disabled */);
- // invoke the method under test (accessibility disabled)
- AccessibilityManager manager = new AccessibilityManager(mContext, mockServiceInterface,
- UserHandle.USER_OWNER);
try {
manager.sendAccessibilityEvent(sentEvent);
fail("No accessibility events are sent if accessibility is disabled");
@@ -202,73 +158,5 @@
// check expected result
assertEquals("Accessibility off. Did you forget to check that?", ise.getMessage());
}
-
- // verify the mock service was properly called
- verify(mockServiceInterface);
- }
-
- /**
- * Determines if an {@link AccessibilityEvent} passed as a method argument
- * matches expectations.
- *
- * @param matched The event to check.
- * @return True if expectations are matched.
- */
- private static AccessibilityEvent eqAccessibilityEvent(AccessibilityEvent matched) {
- reportMatcher(new AccessibilityEventMather(matched));
- return null;
- }
-
- /**
- * Determines if an {@link IAccessibilityManagerClient} passed as a method argument
- * matches expectations which in this case are that any instance is accepted.
- *
- * @return <code>null</code>.
- */
- private static IAccessibilityManagerClient anyIAccessibilityManagerClient() {
- reportMatcher(new AnyIAccessibilityManagerClientMather());
- return null;
- }
-
- /**
- * Matcher for {@link AccessibilityEvent}s.
- */
- private static class AccessibilityEventMather implements IArgumentMatcher {
- private AccessibilityEvent mExpectedEvent;
-
- public AccessibilityEventMather(AccessibilityEvent expectedEvent) {
- mExpectedEvent = expectedEvent;
- }
-
- public boolean matches(Object matched) {
- if (!(matched instanceof AccessibilityEvent)) {
- return false;
- }
- AccessibilityEvent receivedEvent = (AccessibilityEvent) matched;
- return mExpectedEvent.getEventType() == receivedEvent.getEventType();
- }
-
- public void appendTo(StringBuffer buffer) {
- buffer.append("sendAccessibilityEvent()");
- buffer.append(" with event type \"");
- buffer.append(mExpectedEvent.getEventType());
- buffer.append("\"");
- }
- }
-
- /**
- * Matcher for {@link IAccessibilityManagerClient}s.
- */
- private static class AnyIAccessibilityManagerClientMather implements IArgumentMatcher {
- public boolean matches(Object matched) {
- if (!(matched instanceof IAccessibilityManagerClient)) {
- return false;
- }
- return true;
- }
-
- public void appendTo(StringBuffer buffer) {
- buffer.append("addClient() with any IAccessibilityManagerClient");
- }
}
}
diff --git a/services/tests/servicestests/src/com/android/server/MockAccessibilityService.java b/services/tests/servicestests/src/com/android/server/MockAccessibilityService.java
index 1bc9b86..e1c5cee 100644
--- a/services/tests/servicestests/src/com/android/server/MockAccessibilityService.java
+++ b/services/tests/servicestests/src/com/android/server/MockAccessibilityService.java
@@ -62,7 +62,7 @@
*/
public static AccessibilityServiceInfo createDefaultInfo() {
AccessibilityServiceInfo defaultInfo = new AccessibilityServiceInfo();
- defaultInfo.eventTypes = AccessibilityEvent.TYPE_VIEW_CLICKED;
+ defaultInfo.eventTypes = AccessibilityEvent.TYPE_ANNOUNCEMENT;
defaultInfo.feedbackType = AccessibilityServiceInfo.FEEDBACK_AUDIBLE;
defaultInfo.flags = 0;
defaultInfo.notificationTimeout = 0;