summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/content/res/AssetManager.java7
-rw-r--r--core/java/android/os/ExternalVibration.java1
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java97
-rw-r--r--core/tests/coretests/src/android/os/ExternalVibrationTest.java47
-rw-r--r--packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java51
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java138
-rw-r--r--services/core/java/com/android/server/location/GnssConfiguration.java9
-rw-r--r--services/core/java/com/android/server/location/GnssLocationProvider.java13
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java44
-rw-r--r--services/core/java/com/android/server/pm/Settings.java1
10 files changed, 310 insertions, 98 deletions
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index a70eff9fc810..72df39932d20 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -1157,8 +1157,11 @@ public final class AssetManager implements AutoCloseable {
}
}
- if (mObject != 0) {
- nativeDestroy(mObject);
+ synchronized (this) {
+ if (mObject != 0) {
+ nativeDestroy(mObject);
+ mObject = 0;
+ }
}
}
diff --git a/core/java/android/os/ExternalVibration.java b/core/java/android/os/ExternalVibration.java
index 37ca868598f5..041d21fabd6f 100644
--- a/core/java/android/os/ExternalVibration.java
+++ b/core/java/android/os/ExternalVibration.java
@@ -157,7 +157,6 @@ public class ExternalVibration implements Parcelable {
out.writeInt(mUid);
out.writeString(mPkg);
writeAudioAttributes(mAttrs, out, flags);
- out.writeParcelable(mAttrs, flags);
out.writeStrongBinder(mController.asBinder());
out.writeStrongBinder(mToken);
}
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index e671708a1106..d395f5294d6c 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -92,10 +92,7 @@ import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
/**
@@ -425,13 +422,6 @@ public final class InputMethodManager {
int mCursorCandEnd;
/**
- * Initial startInput with {@link StartInputReason.WINDOW_FOCUS_GAIN} is executed
- * in a background thread. Later, if there is an actual startInput it will wait on
- * main thread till the background thread completes.
- */
- private CompletableFuture<Void> mWindowFocusGainFuture;
-
- /**
* The instance that has previously been sent to the input method.
*/
private CursorAnchorInfo mCursorAnchorInfo = null;
@@ -655,14 +645,14 @@ public final class InputMethodManager {
} catch (RemoteException e) {
}
}
- }
- // Check focus again in case that "onWindowFocus" is called before
- // handling this message.
- if (mServedView != null && canStartInput(mServedView)) {
- if (checkFocusNoStartInput(mRestartOnNextWindowFocus)) {
- final int reason = active ? StartInputReason.ACTIVATED_BY_IMMS
- : StartInputReason.DEACTIVATED_BY_IMMS;
- startInputInner(reason, null, 0, 0, 0);
+ // Check focus again in case that "onWindowFocus" is called before
+ // handling this message.
+ if (mServedView != null && canStartInput(mServedView)) {
+ if (checkFocusNoStartInput(mRestartOnNextWindowFocus)) {
+ final int reason = active ? StartInputReason.ACTIVATED_BY_IMMS
+ : StartInputReason.DEACTIVATED_BY_IMMS;
+ startInputInner(reason, null, 0, 0, 0);
+ }
}
}
return;
@@ -1225,10 +1215,6 @@ public final class InputMethodManager {
*/
void clearBindingLocked() {
if (DEBUG) Log.v(TAG, "Clearing binding!");
- if (mWindowFocusGainFuture != null) {
- mWindowFocusGainFuture.cancel(false /* mayInterruptIfRunning */);
- mWindowFocusGainFuture = null;
- }
clearConnectionLocked();
setInputChannelLocked(null);
mBindSequence = -1;
@@ -1612,18 +1598,6 @@ public final class InputMethodManager {
boolean startInputInner(@StartInputReason int startInputReason,
@Nullable IBinder windowGainingFocus, @StartInputFlags int startInputFlags,
@SoftInputModeFlags int softInputMode, int windowFlags) {
- if (startInputReason != StartInputReason.WINDOW_FOCUS_GAIN
- && mWindowFocusGainFuture != null) {
- try {
- mWindowFocusGainFuture.get();
- } catch (ExecutionException | InterruptedException e) {
- // do nothing
- } catch (CancellationException e) {
- // window no longer has focus.
- return true;
- }
- }
-
final View view;
synchronized (mH) {
view = mServedView;
@@ -1977,38 +1951,31 @@ public final class InputMethodManager {
startInputFlags |= StartInputFlags.FIRST_WINDOW_FOCUS_GAIN;
}
- final boolean forceNewFocus1 = forceNewFocus;
- final int startInputFlags1 = startInputFlags;
- if (mWindowFocusGainFuture != null) {
- mWindowFocusGainFuture.cancel(false/* mayInterruptIfRunning */);
- }
- mWindowFocusGainFuture = CompletableFuture.runAsync(() -> {
- if (checkFocusNoStartInput(forceNewFocus1)) {
- // We need to restart input on the current focus view. This
- // should be done in conjunction with telling the system service
- // about the window gaining focus, to help make the transition
- // smooth.
- if (startInputInner(StartInputReason.WINDOW_FOCUS_GAIN, rootView.getWindowToken(),
- startInputFlags1, softInputMode, windowFlags)) {
- return;
- }
+ if (checkFocusNoStartInput(forceNewFocus)) {
+ // We need to restart input on the current focus view. This
+ // should be done in conjunction with telling the system service
+ // about the window gaining focus, to help make the transition
+ // smooth.
+ if (startInputInner(StartInputReason.WINDOW_FOCUS_GAIN, rootView.getWindowToken(),
+ startInputFlags, softInputMode, windowFlags)) {
+ return;
}
+ }
- // For some reason we didn't do a startInput + windowFocusGain, so
- // we'll just do a window focus gain and call it a day.
- synchronized (mH) {
- try {
- if (DEBUG) Log.v(TAG, "Reporting focus gain, without startInput");
- mService.startInputOrWindowGainedFocus(
- StartInputReason.WINDOW_FOCUS_GAIN_REPORT_ONLY, mClient,
- rootView.getWindowToken(), startInputFlags1, softInputMode, windowFlags,
- null, null, 0 /* missingMethodFlags */,
- rootView.getContext().getApplicationInfo().targetSdkVersion);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ // For some reason we didn't do a startInput + windowFocusGain, so
+ // we'll just do a window focus gain and call it a day.
+ synchronized (mH) {
+ try {
+ if (DEBUG) Log.v(TAG, "Reporting focus gain, without startInput");
+ mService.startInputOrWindowGainedFocus(
+ StartInputReason.WINDOW_FOCUS_GAIN_REPORT_ONLY, mClient,
+ rootView.getWindowToken(), startInputFlags, softInputMode, windowFlags,
+ null, null, 0 /* missingMethodFlags */,
+ rootView.getContext().getApplicationInfo().targetSdkVersion);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
- });
+ }
}
/** @hide */
@@ -2023,10 +1990,6 @@ public final class InputMethodManager {
// If the mCurRootView is losing window focus, release the strong reference to it
// so as not to prevent it from being garbage-collected.
mCurRootView = null;
- if (mWindowFocusGainFuture != null) {
- mWindowFocusGainFuture.cancel(false /* mayInterruptIfRunning */);
- mWindowFocusGainFuture = null;
- }
} else {
if (DEBUG) {
Log.v(TAG, "Ignoring onPreWindowFocus()."
diff --git a/core/tests/coretests/src/android/os/ExternalVibrationTest.java b/core/tests/coretests/src/android/os/ExternalVibrationTest.java
new file mode 100644
index 000000000000..3b872d5a7ff1
--- /dev/null
+++ b/core/tests/coretests/src/android/os/ExternalVibrationTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2020 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.os;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.Mockito.mock;
+
+import android.media.AudioAttributes;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ExternalVibrationTest {
+ @Test
+ public void testSerialization() {
+ AudioAttributes audio = new AudioAttributes.Builder().build();
+ IExternalVibrationController controller = mock(IExternalVibrationController.class);
+ ExternalVibration original = new ExternalVibration(
+ 123, // uid
+ "pkg",
+ audio,
+ controller);
+ Parcel p = Parcel.obtain();
+ original.writeToParcel(p, 0);
+ p.setDataPosition(0);
+ ExternalVibration restored = ExternalVibration.CREATOR.createFromParcel(p);
+ assertEquals(original, restored);
+ }
+}
+
diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
index 7a74dba27dce..b2eedaf085cf 100644
--- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
@@ -195,20 +195,32 @@ public class AppOpsControllerImpl implements AppOpsController,
mNotedItems.remove(item);
if (DEBUG) Log.w(TAG, "Removed item: " + item.toString());
}
- notifySuscribers(code, uid, packageName, false);
+ boolean active;
+ // Check if the item is also active
+ synchronized (mActiveItems) {
+ active = getAppOpItem(mActiveItems, code, uid, packageName) != null;
+ }
+ if (!active) {
+ notifySuscribers(code, uid, packageName, false);
+ }
}
- private void addNoted(int code, int uid, String packageName) {
+ private boolean addNoted(int code, int uid, String packageName) {
AppOpItem item;
+ boolean createdNew = false;
synchronized (mNotedItems) {
item = getAppOpItem(mNotedItems, code, uid, packageName);
if (item == null) {
item = new AppOpItem(code, uid, packageName, System.currentTimeMillis());
mNotedItems.add(item);
if (DEBUG) Log.w(TAG, "Added item: " + item.toString());
+ createdNew = true;
}
}
+ // We should keep this so we make sure it cannot time out.
+ mBGHandler.removeCallbacksAndMessages(item);
mBGHandler.scheduleRemoval(item, NOTED_OP_TIME_DELAY_MS);
+ return createdNew;
}
/**
@@ -255,23 +267,46 @@ public class AppOpsControllerImpl implements AppOpsController,
@Override
public void onOpActiveChanged(int code, int uid, String packageName, boolean active) {
- if (updateActives(code, uid, packageName, active)) {
- notifySuscribers(code, uid, packageName, active);
+ if (DEBUG) {
+ Log.w(TAG, String.format("onActiveChanged(%d,%d,%s,%s", code, uid, packageName,
+ Boolean.toString(active)));
+ }
+ boolean activeChanged = updateActives(code, uid, packageName, active);
+ if (!activeChanged) return; // early return
+ // Check if the item is also noted, in that case, there's no update.
+ boolean alsoNoted;
+ synchronized (mNotedItems) {
+ alsoNoted = getAppOpItem(mNotedItems, code, uid, packageName) != null;
+ }
+ // If active is true, we only send the update if the op is not actively noted (already true)
+ // If active is false, we only send the update if the op is not actively noted (prevent
+ // early removal)
+ if (!alsoNoted) {
+ mBGHandler.post(() -> notifySuscribers(code, uid, packageName, active));
}
}
@Override
public void onOpNoted(int code, int uid, String packageName, int result) {
if (DEBUG) {
- Log.w(TAG, "Op: " + code + " with result " + AppOpsManager.MODE_NAMES[result]);
+ Log.w(TAG, "Noted op: " + code + " with result "
+ + AppOpsManager.MODE_NAMES[result] + " for package " + packageName);
}
if (result != AppOpsManager.MODE_ALLOWED) return;
- addNoted(code, uid, packageName);
- notifySuscribers(code, uid, packageName, true);
+ boolean notedAdded = addNoted(code, uid, packageName);
+ if (!notedAdded) return; // early return
+ boolean alsoActive;
+ synchronized (mActiveItems) {
+ alsoActive = getAppOpItem(mActiveItems, code, uid, packageName) != null;
+ }
+ if (!alsoActive) {
+ mBGHandler.post(() -> notifySuscribers(code, uid, packageName, true));
+ }
}
private void notifySuscribers(int code, int uid, String packageName, boolean active) {
if (mCallbacksByCode.containsKey(code)) {
+ if (DEBUG) Log.d(TAG, "Notifying of change in package " + packageName);
for (Callback cb: mCallbacksByCode.get(code)) {
cb.onActiveStateChanged(code, uid, packageName, active);
}
@@ -295,7 +330,7 @@ public class AppOpsControllerImpl implements AppOpsController,
}
- protected final class H extends Handler {
+ protected class H extends Handler {
H(Looper looper) {
super(looper);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java
index 59d5c243af73..a1842f821fe0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java
@@ -28,6 +28,8 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static java.lang.Thread.sleep;
+
import android.app.AppOpsManager;
import android.content.pm.PackageManager;
import android.os.UserHandle;
@@ -36,7 +38,6 @@ import android.testing.TestableLooper;
import androidx.test.filters.SmallTest;
-import com.android.systemui.Dependency;
import com.android.systemui.SysuiTestCase;
import org.junit.Before;
@@ -45,6 +46,8 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.List;
+
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@@ -63,14 +66,16 @@ public class AppOpsControllerTest extends SysuiTestCase {
private AppOpsControllerImpl.H mMockHandler;
private AppOpsControllerImpl mController;
+ private TestableLooper mTestableLooper;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+ mTestableLooper = TestableLooper.get(this);
getContext().addMockSystemService(AppOpsManager.class, mAppOpsManager);
- mController = new AppOpsControllerImpl(mContext, Dependency.get(Dependency.BG_LOOPER));
+ mController = new AppOpsControllerImpl(mContext, mTestableLooper.getLooper());
}
@Test
@@ -94,6 +99,7 @@ public class AppOpsControllerTest extends SysuiTestCase {
AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
mController.onOpNoted(AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME,
AppOpsManager.MODE_ALLOWED);
+ mTestableLooper.processAllMessages();
verify(mCallback).onActiveStateChanged(AppOpsManager.OP_RECORD_AUDIO,
TEST_UID, TEST_PACKAGE_NAME, true);
}
@@ -103,6 +109,7 @@ public class AppOpsControllerTest extends SysuiTestCase {
mController.addCallback(new int[]{AppOpsManager.OP_FINE_LOCATION}, mCallback);
mController.onOpActiveChanged(
AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
+ mTestableLooper.processAllMessages();
verify(mCallback, never()).onActiveStateChanged(
anyInt(), anyInt(), anyString(), anyBoolean());
}
@@ -113,6 +120,7 @@ public class AppOpsControllerTest extends SysuiTestCase {
mController.removeCallback(new int[]{AppOpsManager.OP_RECORD_AUDIO}, mCallback);
mController.onOpActiveChanged(
AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
+ mTestableLooper.processAllMessages();
verify(mCallback, never()).onActiveStateChanged(
anyInt(), anyInt(), anyString(), anyBoolean());
}
@@ -123,6 +131,7 @@ public class AppOpsControllerTest extends SysuiTestCase {
mController.removeCallback(new int[]{AppOpsManager.OP_CAMERA}, mCallback);
mController.onOpActiveChanged(
AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
+ mTestableLooper.processAllMessages();
verify(mCallback).onActiveStateChanged(AppOpsManager.OP_RECORD_AUDIO,
TEST_UID, TEST_PACKAGE_NAME, true);
}
@@ -185,4 +194,129 @@ public class AppOpsControllerTest extends SysuiTestCase {
verify(mMockHandler).removeCallbacksAndMessages(null);
assertTrue(mController.getActiveAppOps().isEmpty());
}
+
+ @Test
+ public void noDoubleUpdateOnOpNoted() {
+ mController.setBGHandler(mMockHandler);
+
+ mController.onOpNoted(AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME,
+ AppOpsManager.MODE_ALLOWED);
+ mController.onOpNoted(AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME,
+ AppOpsManager.MODE_ALLOWED);
+
+ // Only one post to notify subscribers
+ verify(mMockHandler, times(1)).post(any());
+
+ List<AppOpItem> list = mController.getActiveAppOps();
+ assertEquals(1, list.size());
+ }
+
+ @Test
+ public void onDoubleOPNoted_scheduleTwiceForRemoval() {
+ mController.setBGHandler(mMockHandler);
+
+ mController.onOpNoted(AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME,
+ AppOpsManager.MODE_ALLOWED);
+ mController.onOpNoted(AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME,
+ AppOpsManager.MODE_ALLOWED);
+
+ // Only one post to notify subscribers
+ verify(mMockHandler, times(2)).scheduleRemoval(any(), anyLong());
+ }
+
+ @Test
+ public void testActiveOpNotRemovedAfterNoted() throws InterruptedException {
+ // Replaces the timeout delay with 5 ms
+ AppOpsControllerImpl.H testHandler = mController.new H(mTestableLooper.getLooper()) {
+ @Override
+ public void scheduleRemoval(AppOpItem item, long timeToRemoval) {
+ super.scheduleRemoval(item, 5L);
+ }
+ };
+
+ mController.addCallback(new int[]{AppOpsManager.OP_FINE_LOCATION}, mCallback);
+ mController.setBGHandler(testHandler);
+
+ mController.onOpActiveChanged(
+ AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, true);
+
+ mController.onOpNoted(AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME,
+ AppOpsManager.MODE_ALLOWED);
+
+ mTestableLooper.processAllMessages();
+ List<AppOpItem> list = mController.getActiveAppOps();
+ verify(mCallback).onActiveStateChanged(
+ AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, true);
+
+ // Duplicates are not removed between active and noted
+ assertEquals(2, list.size());
+
+ sleep(10L);
+
+ mTestableLooper.processAllMessages();
+
+ verify(mCallback, never()).onActiveStateChanged(
+ AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, false);
+ list = mController.getActiveAppOps();
+ assertEquals(1, list.size());
+ }
+
+ @Test
+ public void testNotedNotRemovedAfterActive() {
+ mController.addCallback(new int[]{AppOpsManager.OP_FINE_LOCATION}, mCallback);
+
+ mController.onOpNoted(AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME,
+ AppOpsManager.MODE_ALLOWED);
+
+ mController.onOpActiveChanged(
+ AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, true);
+
+ mTestableLooper.processAllMessages();
+ List<AppOpItem> list = mController.getActiveAppOps();
+ verify(mCallback).onActiveStateChanged(
+ AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, true);
+
+ // Duplicates are not removed between active and noted
+ assertEquals(2, list.size());
+
+ mController.onOpActiveChanged(
+ AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, false);
+
+ mTestableLooper.processAllMessages();
+
+ verify(mCallback, never()).onActiveStateChanged(
+ AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, false);
+ list = mController.getActiveAppOps();
+ assertEquals(1, list.size());
+ }
+
+ @Test
+ public void testNotedAndActiveOnlyOneCall() {
+ mController.addCallback(new int[]{AppOpsManager.OP_FINE_LOCATION}, mCallback);
+
+ mController.onOpNoted(AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME,
+ AppOpsManager.MODE_ALLOWED);
+
+ mController.onOpActiveChanged(
+ AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, true);
+
+ mTestableLooper.processAllMessages();
+ verify(mCallback).onActiveStateChanged(
+ AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, true);
+ }
+
+ @Test
+ public void testActiveAndNotedOnlyOneCall() {
+ mController.addCallback(new int[]{AppOpsManager.OP_FINE_LOCATION}, mCallback);
+
+ mController.onOpActiveChanged(
+ AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, true);
+
+ mController.onOpNoted(AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME,
+ AppOpsManager.MODE_ALLOWED);
+
+ mTestableLooper.processAllMessages();
+ verify(mCallback).onActiveStateChanged(
+ AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, true);
+ }
}
diff --git a/services/core/java/com/android/server/location/GnssConfiguration.java b/services/core/java/com/android/server/location/GnssConfiguration.java
index 86a84e312899..18d9f69c9735 100644
--- a/services/core/java/com/android/server/location/GnssConfiguration.java
+++ b/services/core/java/com/android/server/location/GnssConfiguration.java
@@ -79,7 +79,7 @@ class GnssConfiguration {
// Represents an HAL interface version. Instances of this class are created in the JNI layer
// and returned through native methods.
- private static class HalInterfaceVersion {
+ static class HalInterfaceVersion {
final int mMajor;
final int mMinor;
@@ -205,6 +205,10 @@ class GnssConfiguration {
native_set_satellite_blacklist(constellations, svids);
}
+ HalInterfaceVersion getHalInterfaceVersion() {
+ return native_get_gnss_configuration_version();
+ }
+
interface SetCarrierProperty {
boolean set(int value);
}
@@ -231,8 +235,7 @@ class GnssConfiguration {
logConfigurations();
- final HalInterfaceVersion gnssConfigurationIfaceVersion =
- native_get_gnss_configuration_version();
+ final HalInterfaceVersion gnssConfigurationIfaceVersion = getHalInterfaceVersion();
if (gnssConfigurationIfaceVersion != null) {
// Set to a range checked value.
if (isConfigEsExtensionSecSupported(gnssConfigurationIfaceVersion)
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 8d0397ed9aec..77823161e279 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -774,10 +774,15 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
locationRequest.setProvider(provider);
- // Ignore location settings if in emergency mode.
- if (isUserEmergency && mNIHandler.getInEmergency()) {
- locationRequest.setLocationSettingsIgnored(true);
- durationMillis *= EMERGENCY_LOCATION_UPDATE_DURATION_MULTIPLIER;
+ // Ignore location settings if in emergency mode. This is only allowed for
+ // isUserEmergency request (introduced in HAL v2.0), or DBH request in HAL v1.1.
+ if (mNIHandler.getInEmergency()) {
+ GnssConfiguration.HalInterfaceVersion halVersion =
+ mGnssConfiguration.getHalInterfaceVersion();
+ if (isUserEmergency || (halVersion.mMajor < 2 && !independentFromGnss)) {
+ locationRequest.setLocationSettingsIgnored(true);
+ durationMillis *= EMERGENCY_LOCATION_UPDATE_DURATION_MULTIPLIER;
+ }
}
Log.i(TAG,
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index ce0c21cb3f1a..e82102f3379d 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -17556,36 +17556,48 @@ public class PackageManagerService extends IPackageManager.Stub
int count = 0;
final String packageName = pkg.packageName;
+ boolean handlesWebUris = false;
+ final boolean alreadyVerified;
synchronized (mPackages) {
// If this is a new install and we see that we've already run verification for this
// package, we have nothing to do: it means the state was restored from backup.
- if (!replacing) {
- IntentFilterVerificationInfo ivi =
- mSettings.getIntentFilterVerificationLPr(packageName);
- if (ivi != null) {
- if (DEBUG_DOMAIN_VERIFICATION) {
- Slog.i(TAG, "Package " + packageName+ " already verified: status="
- + ivi.getStatusString());
- }
- return;
+ final IntentFilterVerificationInfo ivi =
+ mSettings.getIntentFilterVerificationLPr(packageName);
+ alreadyVerified = (ivi != null);
+ if (!replacing && alreadyVerified) {
+ if (DEBUG_DOMAIN_VERIFICATION) {
+ Slog.i(TAG, "Package " + packageName + " already verified: status="
+ + ivi.getStatusString());
}
+ return;
}
- // If any filters need to be verified, then all need to be.
+ // If any filters need to be verified, then all need to be. In addition, we need to
+ // know whether an updating app has any web navigation intent filters, to re-
+ // examine handling policy even if not re-verifying.
boolean needToVerify = false;
for (PackageParser.Activity a : pkg.activities) {
for (ActivityIntentInfo filter : a.intents) {
+ if (filter.handlesWebUris(true)) {
+ handlesWebUris = true;
+ }
if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
if (DEBUG_DOMAIN_VERIFICATION) {
Slog.d(TAG,
"Intent filter needs verification, so processing all filters");
}
needToVerify = true;
+ // It's safe to break out here because filter.needsVerification()
+ // can only be true if filter.handlesWebUris(true) returns true, so
+ // we've already noted that.
break;
}
}
}
+ // Note whether this app publishes any web navigation handling support at all,
+ // and whether there are any web-nav filters that fit the profile for running
+ // a verification pass now.
if (needToVerify) {
final int verificationId = mIntentFilterVerificationToken++;
for (PackageParser.Activity a : pkg.activities) {
@@ -17603,13 +17615,23 @@ public class PackageManagerService extends IPackageManager.Stub
}
if (count > 0) {
+ // count > 0 means that we're running a full verification pass
if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
+ " IntentFilter verification" + (count > 1 ? "s" : "")
+ " for userId:" + userId);
mIntentFilterVerifier.startVerifications(userId);
+ } else if (alreadyVerified && handlesWebUris) {
+ // App used autoVerify in the past, no longer does, but still handles web
+ // navigation starts.
+ if (DEBUG_DOMAIN_VERIFICATION) {
+ Slog.d(TAG, "App changed web filters but no longer verifying - resetting policy");
+ }
+ synchronized (mPackages) {
+ clearIntentFilterVerificationsLPw(packageName, userId);
+ }
} else {
if (DEBUG_DOMAIN_VERIFICATION) {
- Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
+ Slog.d(TAG, "No web filters or no prior verify policy for " + packageName);
}
}
}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 994fca80e672..9fa12b2d5c67 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -1252,6 +1252,7 @@ public final class Settings {
return false;
}
ps.clearDomainVerificationStatusForUser(userId);
+ ps.setIntentFilterVerificationInfo(null);
return true;
}