release-request-94bbded7-c270-40fa-9a74-fedecfd046c6-for-git_oc-release-4034177 snap-temp-L73200000066785187
Change-Id: I0eaf43efcd1359602b8f8b3a1896e3756588df7c
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 268a105b..a155de3 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -846,8 +846,9 @@
// Calling start activity from outside an activity without FLAG_ACTIVITY_NEW_TASK is
// generally not allowed, except if the caller specifies the task id the activity should
// be launched in.
- if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0
- && options != null && ActivityOptions.fromBundle(options).getLaunchTaskId() == -1) {
+ if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) == 0
+ && (options == null
+ || ActivityOptions.fromBundle(options).getLaunchTaskId() == -1)) {
throw new AndroidRuntimeException(
"Calling startActivity() from outside of an Activity "
+ " context requires the FLAG_ACTIVITY_NEW_TASK flag."
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 2c33b60..2bb5f28 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -678,9 +678,16 @@
} finally {
mIsCreating = false;
if (mSurfaceControl != null && !mSurfaceCreated) {
- mSurfaceControl.destroy();
mSurface.release();
- mSurfaceControl = null;
+ // If we are not in the stopped state, then the destruction of the Surface
+ // represents a visual change we need to display, and we should go ahead
+ // and destroy the SurfaceControl. However if we are in the stopped state,
+ // we can just leave the Surface around so it can be a part of animations,
+ // and we let the life-time be tied to the parent surface.
+ if (!mWindowStopped) {
+ mSurfaceControl.destroy();
+ mSurfaceControl = null;
+ }
}
}
} catch (Exception ex) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 2d48295..5b51c16 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -19794,7 +19794,6 @@
&& (mForegroundInfo == null || mForegroundInfo.mDrawable == null)) {
mPrivateFlags |= PFLAG_SKIP_DRAW;
}
- requestLayout();
invalidate();
}
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index 8a13c0c..eecfdca 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -618,8 +618,7 @@
public static final int TYPE_WINDOW_CONTENT_CHANGED = 0x00000800;
/**
- * Represents the event of scrolling a view. This event type is generally not sent directly.
- * @see View#onScrollChanged(int, int, int, int)
+ * Represents the event of scrolling a view.
*/
public static final int TYPE_VIEW_SCROLLED = 0x00001000;
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index d456989..7bdd6da 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -737,7 +737,6 @@
mInputText.setFilters(new InputFilter[] {
new InputTextFilter()
});
- mInputText.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE);
mInputText.setRawInputType(InputType.TYPE_CLASS_NUMBER);
mInputText.setImeOptions(EditorInfo.IME_ACTION_DONE);
@@ -771,12 +770,6 @@
if (getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
}
-
- // Should be focusable by default, as the text view whose visibility changes is focusable
- if (getFocusable() == View.FOCUSABLE_AUTO) {
- setFocusable(View.FOCUSABLE);
- setFocusableInTouchMode(true);
- }
}
@Override
@@ -863,7 +856,7 @@
switch (action) {
case MotionEvent.ACTION_DOWN: {
removeAllCallbacks();
- hideSoftInput();
+ mInputText.setVisibility(View.INVISIBLE);
mLastDownOrMoveEventY = mLastDownEventY = event.getY();
mLastDownEventTime = event.getEventTime();
mIgnoreMoveEvents = false;
@@ -890,9 +883,11 @@
mFlingScroller.forceFinished(true);
mAdjustScroller.forceFinished(true);
} else if (mLastDownEventY < mTopSelectionDividerTop) {
+ hideSoftInput();
postChangeCurrentByOneFromLongPress(
false, ViewConfiguration.getLongPressTimeout());
} else if (mLastDownEventY > mBottomSelectionDividerBottom) {
+ hideSoftInput();
postChangeCurrentByOneFromLongPress(
true, ViewConfiguration.getLongPressTimeout());
} else {
@@ -1125,7 +1120,6 @@
@Override
public void scrollBy(int x, int y) {
int[] selectorIndices = mSelectorIndices;
- int startScrollOffset = mCurrentScrollOffset;
if (!mWrapSelectorWheel && y > 0
&& selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX] <= mMinValue) {
mCurrentScrollOffset = mInitialScrollOffset;
@@ -1153,9 +1147,6 @@
mCurrentScrollOffset = mInitialScrollOffset;
}
}
- if (startScrollOffset != mCurrentScrollOffset) {
- onScrollChanged(0, mCurrentScrollOffset, 0, startScrollOffset);
- }
}
@Override
@@ -1744,10 +1735,7 @@
}
int previous = mValue;
mValue = current;
- // If we're flinging, we'll update the text view at the end when it becomes visible
- if (mScrollState != OnScrollListener.SCROLL_STATE_FLING) {
- updateInputTextView();
- }
+ updateInputTextView();
if (notifyChange) {
notifyChange(previous, current);
}
@@ -1764,7 +1752,7 @@
*/
private void changeValueByOne(boolean increment) {
if (mHasSelectorWheel) {
- hideSoftInput();
+ mInputText.setVisibility(View.INVISIBLE);
if (!moveToFinalScrollerPosition(mFlingScroller)) {
moveToFinalScrollerPosition(mAdjustScroller);
}
@@ -1811,8 +1799,9 @@
*/
private void onScrollerFinished(Scroller scroller) {
if (scroller == mFlingScroller) {
- ensureScrollWheelAdjusted();
- updateInputTextView();
+ if (!ensureScrollWheelAdjusted()) {
+ updateInputTextView();
+ }
onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
} else {
if (mScrollState != OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
@@ -1948,25 +1937,9 @@
*/
String text = (mDisplayedValues == null) ? formatNumber(mValue)
: mDisplayedValues[mValue - mMinValue];
- if (!TextUtils.isEmpty(text)) {
- CharSequence beforeText = mInputText.getText();
- if (!text.equals(beforeText.toString())) {
- mInputText.setText(text);
- if (mAccessibilityNodeProvider != null) {
- AccessibilityEvent event = AccessibilityEvent.obtain(
- AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
- mInputText.onInitializeAccessibilityEvent(event);
- mInputText.onPopulateAccessibilityEvent(event);
- event.setFromIndex(0);
- event.setRemovedCount(beforeText.length());
- event.setAddedCount(text.length());
- event.setBeforeText(beforeText);
- event.setSource(NumberPicker.this,
- AccessibilityNodeProviderImpl.VIRTUAL_VIEW_ID_INPUT);
- requestSendAccessibilityEvent(NumberPicker.this, event);
- }
- return true;
- }
+ if (!TextUtils.isEmpty(text) && !text.equals(mInputText.getText().toString())) {
+ mInputText.setText(text);
+ return true;
}
return false;
diff --git a/core/java/com/android/internal/notification/SystemNotificationChannels.java b/core/java/com/android/internal/notification/SystemNotificationChannels.java
index d279746..797cf2b 100644
--- a/core/java/com/android/internal/notification/SystemNotificationChannels.java
+++ b/core/java/com/android/internal/notification/SystemNotificationChannels.java
@@ -47,7 +47,6 @@
public static String RETAIL_MODE = "RETAIL_MODE";
public static String USB = "USB";
public static String FOREGROUND_SERVICE = "FOREGROUND_SERVICE";
- public static String ALERT_WINDOW = "ALERT_WINDOW";
public static void createAll(Context context) {
final NotificationManager nm = context.getSystemService(NotificationManager.class);
@@ -138,11 +137,6 @@
context.getString(R.string.notification_channel_foreground_service),
NotificationManager.IMPORTANCE_MIN));
- channelsList.add(new NotificationChannel(
- ALERT_WINDOW,
- context.getString(R.string.alert_windows_notification_channel_name),
- NotificationManager.IMPORTANCE_MIN));
-
nm.createNotificationChannels(channelsList);
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index f28e862..17ef77c 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -185,7 +185,7 @@
switch (msg.what) {
case MSG_UPDATE_WAKELOCKS:
synchronized (BatteryStatsImpl.this) {
- updateCpuTimeLocked();
+ updateCpuTimeLocked(false /* updateCpuFreqData */);
}
if (cb != null) {
cb.batteryNeedsCpuUpdate();
@@ -3480,7 +3480,7 @@
Slog.d(TAG, "Updating cpu time because screen is now " +
(unpluggedScreenOff ? "off" : "on"));
}
- updateCpuTimeLocked();
+ updateCpuTimeLocked(true /* updateCpuFreqData */);
mOnBatteryScreenOffTimeBase.setRunning(unpluggedScreenOff, uptime, realtime);
for (int i = 0; i < mUidStats.size(); i++) {
mUidStats.valueAt(i).updateOnBatteryScreenOffBgTimeBase(uptime, realtime);
@@ -10002,7 +10002,7 @@
* and we are on battery with screen off, we give more of the cpu time to those apps holding
* wakelocks. If the screen is on, we just assign the actual cpu time an app used.
*/
- public void updateCpuTimeLocked() {
+ public void updateCpuTimeLocked(boolean updateCpuFreqData) {
if (mPowerProfile == null) {
return;
}
@@ -10117,7 +10117,9 @@
}
});
- readKernelUidCpuFreqTimesLocked();
+ if (updateCpuFreqData) {
+ readKernelUidCpuFreqTimesLocked();
+ }
final long elapse = (mClocks.elapsedRealtime() - startTimeMs);
if (DEBUG_ENERGY_CPU || (elapse >= 100)) {
diff --git a/core/res/res/values-watch/config.xml b/core/res/res/values-watch/config.xml
index 98dc4cf..f26d6ed 100644
--- a/core/res/res/values-watch/config.xml
+++ b/core/res/res/values-watch/config.xml
@@ -63,11 +63,8 @@
Set to true for watch devices. -->
<bool name="config_focusScrollContainersInTouchMode">true</bool>
- <!-- The small screens of watch devices makes multi-window support undesireable. -->
- <bool name="config_supportsMultiWindow">false</bool>
+ <!-- Enable generic multi-window in order to support Activity in virtual display. -->
+ <bool name="config_supportsMultiWindow">true</bool>
+ <bool name="config_supportsMultiDisplay">true</bool>
<bool name="config_supportsSplitScreenMultiWindow">false</bool>
-
- <!-- Disable Multi-Display because of small screen space and lack of external display connection
- options. -->
- <bool name="config_supportsMultiDisplay">false</bool>
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index fcabe31..f747d3d 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3225,7 +3225,7 @@
<skip />
<!-- Name of notification channel the system post notification to inform the use about apps
that are drawing ui on-top of other apps (alert-windows) [CHAR LIMIT=NONE] -->
- <string name="alert_windows_notification_channel_name">App activity</string>
+ <string name="alert_windows_notification_channel_name"><xliff:g id="name" example="Google Maps">%s</xliff:g> displaying over other apps</string>
<!-- Notification title when an application is displaying ui on-top of other apps
[CHAR LIMIT=30] -->
<string name="alert_windows_notification_title"><xliff:g id="name" example="Google Maps">%s</xliff:g> is displaying over other apps</string>
diff --git a/core/tests/coretests/src/android/transition/FadeTransitionTest.java b/core/tests/coretests/src/android/transition/FadeTransitionTest.java
index 7e7e815..0140a04 100644
--- a/core/tests/coretests/src/android/transition/FadeTransitionTest.java
+++ b/core/tests/coretests/src/android/transition/FadeTransitionTest.java
@@ -50,7 +50,7 @@
TransitionLatch latch = setVisibilityInTransition(fadeOut, R.id.square1, View.INVISIBLE);
assertTrue(latch.startLatch.await(200, TimeUnit.MILLISECONDS));
assertEquals(View.VISIBLE, square1.getVisibility());
- Thread.sleep(100);
+ waitForAnimation();
assertFalse(square1.getTransitionAlpha() == 0 || square1.getTransitionAlpha() == 1);
assertTrue(latch.endLatch.await(400, TimeUnit.MILLISECONDS));
assertEquals(1.0f, square1.getTransitionAlpha());
@@ -60,7 +60,7 @@
latch = setVisibilityInTransition(fadeIn, R.id.square1, View.VISIBLE);
assertTrue(latch.startLatch.await(200, TimeUnit.MILLISECONDS));
assertEquals(View.VISIBLE, square1.getVisibility());
- Thread.sleep(100);
+ waitForAnimation();
final float transitionAlpha = square1.getTransitionAlpha();
assertTrue("expecting transitionAlpha to be between 0 and 1. Was " + transitionAlpha,
transitionAlpha > 0 && transitionAlpha < 1);
@@ -77,7 +77,7 @@
fadeOut.addListener(fadeOutValueCheck);
TransitionLatch outLatch = setVisibilityInTransition(fadeOut, R.id.square1, View.INVISIBLE);
assertTrue(outLatch.startLatch.await(200, TimeUnit.MILLISECONDS));
- Thread.sleep(100);
+ waitForAnimation();
Fade fadeIn = new Fade(Fade.MODE_IN);
FadeValueCheck fadeInValueCheck = new FadeValueCheck(square1);
@@ -110,7 +110,7 @@
fadeIn.addListener(fadeInValueCheck);
TransitionLatch inLatch = setVisibilityInTransition(fadeIn, R.id.square1, View.VISIBLE);
assertTrue(inLatch.startLatch.await(200, TimeUnit.MILLISECONDS));
- Thread.sleep(100);
+ waitForAnimation();
Fade fadeOut = new Fade(Fade.MODE_OUT);
FadeValueCheck fadeOutValueCheck = new FadeValueCheck(square1);
@@ -145,6 +145,23 @@
return latch;
}
+ /**
+ * Waits for two animation frames to ensure animation values change.
+ */
+ private void waitForAnimation() throws InterruptedException {
+ final CountDownLatch latch = new CountDownLatch(2);
+ mActivity.getWindow().getDecorView().postOnAnimation(new Runnable() {
+ @Override
+ public void run() {
+ latch.countDown();
+ if (latch.getCount() > 0) {
+ mActivity.getWindow().getDecorView().postOnAnimation(this);
+ }
+ }
+ });
+ assertTrue(latch.await(1, TimeUnit.SECONDS));
+ }
+
public static class TransitionLatch implements TransitionListener {
public CountDownLatch startLatch = new CountDownLatch(1);
public CountDownLatch endLatch = new CountDownLatch(1);
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
index b145290..0cf21d2 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
@@ -93,9 +93,9 @@
}
@Override
- protected void onPause() {
- super.onPause();
- if (!isFinishing()) {
+ protected void onStop() {
+ super.onStop();
+ if (!isFinishing() && !isChangingConfigurations()) {
cancel();
}
}
diff --git a/packages/SettingsLib/res/layout/restricted_switch_preference.xml b/packages/SettingsLib/res/layout/restricted_switch_preference.xml
index 0e4ef6b..64b47b6 100644
--- a/packages/SettingsLib/res/layout/restricted_switch_preference.xml
+++ b/packages/SettingsLib/res/layout/restricted_switch_preference.xml
@@ -27,7 +27,7 @@
android:id="@+id/icon_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:minWidth="60dp"
+ android:minWidth="56dp"
android:gravity="start|center_vertical"
android:orientation="horizontal"
android:paddingEnd="12dp"
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index eb513e1..b3565ea 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -521,7 +521,8 @@
public boolean isMetered() {
return mIsScoredNetworkMetered
|| (mConfig != null && mConfig.meteredHint)
- || (mInfo != null && mInfo.getMeteredHint());
+ || (mInfo != null && mInfo.getMeteredHint()
+ || (mNetworkInfo != null && mNetworkInfo.isMetered()));
}
public NetworkInfo getNetworkInfo() {
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
index 56cb0a3..801844b 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
@@ -18,7 +18,6 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
-import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.when;
@@ -237,7 +236,7 @@
homeSp.setFriendlyName("Test Provider");
config.setHomeSp(homeSp);
AccessPoint ap = new AccessPoint(mContext, config);
- assertTrue(ap.isPasspointConfig());
+ assertThat(ap.isPasspointConfig()).isTrue();
}
@Test
@@ -254,8 +253,8 @@
wifiInfo.setNetworkId(configuration.networkId);
accessPoint.update(configuration, wifiInfo, networkInfo);
- assertTrue(accessPoint.isMetered());
- };
+ assertThat(accessPoint.isMetered()).isTrue();
+ }
@Test
public void testIsMetered_returnTrueWhenWifiInfoIsMetered() {
@@ -271,8 +270,25 @@
wifiInfo.setMeteredHint(true);
accessPoint.update(configuration, wifiInfo, networkInfo);
- assertTrue(accessPoint.isMetered());
- };
+ assertThat(accessPoint.isMetered()).isTrue();
+ }
+
+ @Test
+ public void testIsMetered_returnTrueWhenNetworkInfoIsMetered() {
+ WifiConfiguration configuration = createWifiConfiguration();
+
+ NetworkInfo networkInfo =
+ new NetworkInfo(ConnectivityManager.TYPE_WIFI, 2, "WIFI", "WIFI_SUBTYPE");
+ networkInfo.setMetered(true);
+ AccessPoint accessPoint = new AccessPoint(mContext, configuration);
+ WifiInfo wifiInfo = new WifiInfo();
+ wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(configuration.SSID));
+ wifiInfo.setBSSID(configuration.BSSID);
+ wifiInfo.setNetworkId(configuration.networkId);
+ accessPoint.update(configuration, wifiInfo, networkInfo);
+
+ assertThat(accessPoint.isMetered()).isTrue();
+ }
@Test
public void testIsMetered_returnTrueWhenScoredNetworkIsMetered() {
@@ -286,8 +302,24 @@
true /* metered */));
ap.update(mWifiNetworkScoreCache, false /* scoringUiEnabled */);
- assertTrue(ap.isMetered());
- };
+ assertThat(ap.isMetered()).isTrue();
+ }
+
+ @Test
+ public void testIsMetered_returnFalseByDefault() {
+ WifiConfiguration configuration = createWifiConfiguration();
+
+ NetworkInfo networkInfo =
+ new NetworkInfo(ConnectivityManager.TYPE_WIFI, 2, "WIFI", "WIFI_SUBTYPE");
+ AccessPoint accessPoint = new AccessPoint(mContext, configuration);
+ WifiInfo wifiInfo = new WifiInfo();
+ wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(configuration.SSID));
+ wifiInfo.setBSSID(configuration.BSSID);
+ wifiInfo.setNetworkId(configuration.networkId);
+ accessPoint.update(configuration, wifiInfo, networkInfo);
+
+ assertThat(accessPoint.isMetered()).isFalse();
+ }
private AccessPoint createAccessPointWithScanResultCache() {
Bundle bundle = new Bundle();
@@ -400,7 +432,7 @@
String providerFriendlyName = "Test Provider";
AccessPoint ap = new TestAccessPointBuilder(mContext).setFqdn(fqdn)
.setProviderFriendlyName(providerFriendlyName).build();
- assertTrue(ap.isPasspointConfig());
+ assertThat(ap.isPasspointConfig()).isTrue();
assertThat(ap.getPasspointFqdn()).isEqualTo(fqdn);
assertThat(ap.getConfigName()).isEqualTo(providerFriendlyName);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index dbf0724..7697061 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -114,7 +114,6 @@
private boolean mFinishedOnStartup;
private boolean mIgnoreAltTabRelease;
private boolean mIsVisible;
- private boolean mReceivedNewIntent;
// Top level views
private RecentsView mRecentsView;
@@ -128,9 +127,6 @@
private int mFocusTimerDuration;
private DozeTrigger mIterateTrigger;
private final UserInteractionEvent mUserInteractionEvent = new UserInteractionEvent();
- private final Runnable mSendEnterWindowAnimationCompleteRunnable = () -> {
- EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
- };
/**
* A common Runnable to finish Recents by launching Home with an animation depending on the
@@ -390,7 +386,6 @@
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
- mReceivedNewIntent = true;
// Reload the stack view
reloadStackView();
@@ -469,16 +464,7 @@
@Override
public void onEnterAnimationComplete() {
super.onEnterAnimationComplete();
-
- // Workaround for b/28705801, on first docking, we may receive the enter animation callback
- // before the first layout, so in such cases, send the event on the next frame after all
- // the views are laid out and attached (and registered to the EventBus).
- mHandler.removeCallbacks(mSendEnterWindowAnimationCompleteRunnable);
- if (!mReceivedNewIntent) {
- mHandler.post(mSendEnterWindowAnimationCompleteRunnable);
- } else {
- mSendEnterWindowAnimationCompleteRunnable.run();
- }
+ EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
}
@Override
@@ -516,7 +502,6 @@
// Notify that recents is now hidden
mIsVisible = false;
- mReceivedNewIntent = false;
EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, false));
MetricsLogger.hidden(this, MetricsEvent.OVERVIEW_ACTIVITY);
Recents.getTaskLoader().getHighResThumbnailLoader().setVisible(false);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index a903f38..e2e9b1b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -1063,7 +1063,6 @@
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
| Intent.FLAG_ACTIVITY_TASK_ON_HOME);
- Recents.getSystemServices().startActivityAsUserAsync(intent, opts);
HidePipMenuEvent hideMenuEvent = new HidePipMenuEvent();
hideMenuEvent.addPostAnimationCallback(() -> {
Recents.getSystemServices().startActivityAsUserAsync(intent, opts);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsTaskStackAnimationCompletedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsTaskStackAnimationCompletedEvent.java
deleted file mode 100644
index ee0df87..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsTaskStackAnimationCompletedEvent.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent when the in-app animations into Recents completes.
- */
-public class EnterRecentsTaskStackAnimationCompletedEvent extends EventBus.AnimatedEvent {
- // Simple event
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationCompletedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationCompletedEvent.java
index 918875a..b31f320 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationCompletedEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowAnimationCompletedEvent.java
@@ -23,6 +23,6 @@
* we can start in-app animations so that they don't conflict with the window transition into
* Recents.
*/
-public class EnterRecentsWindowAnimationCompletedEvent extends EventBus.AnimatedEvent {
+public class EnterRecentsWindowAnimationCompletedEvent extends EventBus.Event {
// Simple event
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 5f9a8f5..6ad6a15 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -62,7 +62,6 @@
import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
-import com.android.systemui.recents.events.activity.EnterRecentsTaskStackAnimationCompletedEvent;
import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent;
import com.android.systemui.recents.events.activity.HideRecentsEvent;
import com.android.systemui.recents.events.activity.HideStackActionButtonEvent;
@@ -97,6 +96,7 @@
import com.android.systemui.recents.events.ui.focus.FocusPreviousTaskViewEvent;
import com.android.systemui.recents.events.ui.focus.NavigateTaskViewEvent;
import com.android.systemui.recents.misc.DozeTrigger;
+import com.android.systemui.recents.misc.ReferenceCountedTrigger;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.model.Task;
@@ -175,7 +175,11 @@
@ViewDebug.ExportedProperty(category="recents")
private boolean mTaskViewsClipDirty = true;
@ViewDebug.ExportedProperty(category="recents")
- private boolean mAwaitingFirstLayout = true;
+ private boolean mEnterAnimationComplete = false;
+ @ViewDebug.ExportedProperty(category="recents")
+ private boolean mStackReloaded = false;
+ @ViewDebug.ExportedProperty(category="recents")
+ private boolean mFinishedLayoutAfterStackReload = false;
@ViewDebug.ExportedProperty(category="recents")
private boolean mLaunchNextAfterFirstMeasure = false;
@ViewDebug.ExportedProperty(category="recents")
@@ -184,8 +188,6 @@
@ViewDebug.ExportedProperty(category="recents")
private boolean mInMeasureLayout = false;
@ViewDebug.ExportedProperty(category="recents")
- private boolean mEnterAnimationComplete = false;
- @ViewDebug.ExportedProperty(category="recents")
boolean mTouchExplorationEnabled;
@ViewDebug.ExportedProperty(category="recents")
boolean mScreenPinningEnabled;
@@ -355,7 +357,6 @@
// Reset the stack state
readSystemFlags();
mTaskViewsClipDirty = true;
- mEnterAnimationComplete = false;
mUIDozeTrigger.stopDozing();
if (isResumingFromVisible) {
// Animate in the freeform workspace
@@ -370,7 +371,8 @@
// Since we always animate to the same place in (the initial state), always reset the stack
// to the initial state when resuming
- mAwaitingFirstLayout = true;
+ mStackReloaded = true;
+ mFinishedLayoutAfterStackReload = false;
mLaunchNextAfterFirstMeasure = false;
mInitialState = INITIAL_STATE_UPDATE_ALL;
requestLayout();
@@ -1282,13 +1284,13 @@
// TaskViews with the stack so that we can lay them out
boolean resetToInitialState = (width != mLastWidth || height != mLastHeight)
&& mResetToInitialStateWhenResized;
- if (mAwaitingFirstLayout || mInitialState != INITIAL_STATE_UPDATE_NONE
+ if (!mFinishedLayoutAfterStackReload || mInitialState != INITIAL_STATE_UPDATE_NONE
|| resetToInitialState) {
if (mInitialState != INITIAL_STATE_UPDATE_LAYOUT_ONLY || resetToInitialState) {
updateToInitialState();
mResetToInitialStateWhenResized = false;
}
- if (!mAwaitingFirstLayout) {
+ if (mFinishedLayoutAfterStackReload) {
mInitialState = INITIAL_STATE_UPDATE_NONE;
}
}
@@ -1361,10 +1363,15 @@
relayoutTaskViews(AnimationProps.IMMEDIATE);
clipTaskViews();
- if (mAwaitingFirstLayout || !mEnterAnimationComplete) {
- mAwaitingFirstLayout = false;
+ if (!mFinishedLayoutAfterStackReload) {
+ // Prepare the task enter animations (this can be called numerous times)
mInitialState = INITIAL_STATE_UPDATE_NONE;
onFirstLayout();
+
+ if (mStackReloaded) {
+ mFinishedLayoutAfterStackReload = true;
+ tryStartEnterAnimation();
+ }
}
}
@@ -1490,7 +1497,7 @@
updateLayoutAlgorithm(true /* boundScroll */);
// Animate all the tasks into place
- relayoutTaskViews(mAwaitingFirstLayout
+ relayoutTaskViews(!mFinishedLayoutAfterStackReload
? AnimationProps.IMMEDIATE
: new AnimationProps(DEFAULT_SYNC_STACK_DURATION, Interpolators.FAST_OUT_SLOW_IN));
}
@@ -1563,7 +1570,7 @@
@Override
public void onStackTasksUpdated(TaskStack stack) {
- if (mAwaitingFirstLayout) {
+ if (!mFinishedLayoutAfterStackReload) {
return;
}
@@ -1805,7 +1812,7 @@
}
public final void onBusEvent(LaunchNextTaskRequestEvent event) {
- if (mAwaitingFirstLayout) {
+ if (!mFinishedLayoutAfterStackReload) {
mLaunchNextAfterFirstMeasure = true;
return;
}
@@ -2125,39 +2132,45 @@
public final void onBusEvent(EnterRecentsWindowAnimationCompletedEvent event) {
mEnterAnimationComplete = true;
+ tryStartEnterAnimation();
+ }
+
+ private void tryStartEnterAnimation() {
+ if (!mStackReloaded || !mFinishedLayoutAfterStackReload || !mEnterAnimationComplete) {
+ return;
+ }
if (mStack.getTaskCount() > 0) {
// Start the task enter animations
- mAnimationHelper.startEnterAnimation(event.getAnimationTrigger());
+ ReferenceCountedTrigger trigger = new ReferenceCountedTrigger();
+ mAnimationHelper.startEnterAnimation(trigger);
// Add a runnable to the post animation ref counter to clear all the views
- event.addPostAnimationCallback(new Runnable() {
- @Override
- public void run() {
- // Start the dozer to trigger to trigger any UI that shows after a timeout
- if (!Recents.getSystemServices().hasFreeformWorkspaceSupport()) {
- mUIDozeTrigger.startDozing();
- }
+ trigger.addLastDecrementRunnable(() -> {
+ // Start the dozer to trigger to trigger any UI that shows after a timeout
+ if (!Recents.getSystemServices().hasFreeformWorkspaceSupport()) {
+ mUIDozeTrigger.startDozing();
+ }
- // Update the focused state here -- since we only set the focused task without
- // requesting view focus in onFirstLayout(), actually request view focus and
- // animate the focused state if we are alt-tabbing now, after the window enter
- // animation is completed
- if (mFocusedTask != null) {
- RecentsConfiguration config = Recents.getConfiguration();
- RecentsActivityLaunchState launchState = config.getLaunchState();
- setFocusedTask(mStack.indexOfStackTask(mFocusedTask),
- false /* scrollToTask */, launchState.launchedWithAltTab);
- TaskView focusedTaskView = getChildViewForTask(mFocusedTask);
- if (mTouchExplorationEnabled && focusedTaskView != null) {
- focusedTaskView.requestAccessibilityFocus();
- }
+ // Update the focused state here -- since we only set the focused task without
+ // requesting view focus in onFirstLayout(), actually request view focus and
+ // animate the focused state if we are alt-tabbing now, after the window enter
+ // animation is completed
+ if (mFocusedTask != null) {
+ RecentsConfiguration config = Recents.getConfiguration();
+ RecentsActivityLaunchState launchState = config.getLaunchState();
+ setFocusedTask(mStack.indexOfStackTask(mFocusedTask),
+ false /* scrollToTask */, launchState.launchedWithAltTab);
+ TaskView focusedTaskView = getChildViewForTask(mFocusedTask);
+ if (mTouchExplorationEnabled && focusedTaskView != null) {
+ focusedTaskView.requestAccessibilityFocus();
}
-
- EventBus.getDefault().send(new EnterRecentsTaskStackAnimationCompletedEvent());
}
});
}
+
+ // This flag is only used to choreograph the enter animation, so we can reset it here
+ mStackReloaded = false;
}
public final void onBusEvent(UpdateFreeformTaskViewVisibilityEvent event) {
@@ -2235,15 +2248,21 @@
}
public final void onBusEvent(RecentsVisibilityChangedEvent event) {
- if (!event.visible && mTaskViewFocusFrame != null) {
- mTaskViewFocusFrame.moveGridTaskViewFocus(null);
- }
if (!event.visible) {
+ if (mTaskViewFocusFrame != null) {
+ mTaskViewFocusFrame.moveGridTaskViewFocus(null);
+ }
+
List<TaskView> taskViews = new ArrayList<>(getTaskViews());
for (int i = 0; i < taskViews.size(); i++) {
mViewPool.returnViewToPool(taskViews.get(i));
}
clearPrefetchingTask();
+
+ // We can not reset mEnterAnimationComplete in onReload() because when docking the top
+ // task, we can receive the enter animation callback before onReload(), so reset it
+ // here onces Recents is not visible
+ mEnterAnimationComplete = false;
}
}
@@ -2377,7 +2396,7 @@
writer.print(" hasDefRelayout=");
writer.print(mDeferredTaskViewLayoutAnimation != null ? "Y" : "N");
writer.print(" clipDirty="); writer.print(mTaskViewsClipDirty ? "Y" : "N");
- writer.print(" awaitingFirstLayout="); writer.print(mAwaitingFirstLayout ? "Y" : "N");
+ writer.print(" awaitingStackReload="); writer.print(mFinishedLayoutAfterStackReload ? "Y" : "N");
writer.print(" initialState="); writer.print(mInitialState);
writer.print(" inMeasureLayout="); writer.print(mInMeasureLayout ? "Y" : "N");
writer.print(" enterAnimCompleted="); writer.print(mEnterAnimationComplete ? "Y" : "N");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 2a69c1e..a31036f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -29,6 +29,7 @@
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.DejankUtils;
import com.android.keyguard.LatencyTracker;
@@ -97,12 +98,26 @@
private boolean mDeviceWillWakeUp;
private boolean mDeferScrimFadeOut;
+ private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
+ new KeyguardUpdateMonitorCallback() {
+ @Override
+ public void onEmergencyCallAction() {
+
+ // Since we won't get a setOccluded call we have to reset the view manually such that
+ // the bouncer goes away.
+ if (mOccluded) {
+ reset(false /* hideBouncerWhenShowing */);
+ }
+ }
+ };
+
public StatusBarKeyguardViewManager(Context context, ViewMediatorCallback callback,
LockPatternUtils lockPatternUtils) {
mContext = context;
mViewMediatorCallback = callback;
mLockPatternUtils = lockPatternUtils;
mStatusBarWindowManager = Dependency.get(StatusBarWindowManager.class);
+ KeyguardUpdateMonitor.getInstance(context).registerCallback(mUpdateMonitorCallback);
}
public void registerStatusBar(StatusBar statusBar,
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index f7a682a..773a1ee 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -161,7 +161,7 @@
*/
private static final int[] SYSTEM_CREDENTIAL_UIDS = {
Process.WIFI_UID, Process.VPN_UID,
- Process.ROOT_UID };
+ Process.ROOT_UID, Process.SYSTEM_UID };
// This class manages life cycle events for encrypted users on File Based Encryption (FBE)
// devices. The most basic of these is to show/hide notifications about missing features until
diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java
index e3ebf4d..f8baf17 100644
--- a/services/core/java/com/android/server/PinnerService.java
+++ b/services/core/java/com/android/server/PinnerService.java
@@ -16,12 +16,15 @@
package com.android.server;
+import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
@@ -68,6 +71,19 @@
private PinnerHandler mPinnerHandler = null;
+ private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // If this user's camera app has been updated, update pinned files accordingly.
+ if (intent.getAction() == Intent.ACTION_PACKAGE_REPLACED) {
+ Uri packageUri = intent.getData();
+ ApplicationInfo cameraInfo = getCameraInfo(UserHandle.USER_SYSTEM);
+ if (cameraInfo.packageName == packageUri.getSchemeSpecificPart()) {
+ update();
+ }
+ }
+ }
+ };
public PinnerService(Context context) {
super(context);
@@ -76,6 +92,11 @@
mShouldPinCamera = context.getResources().getBoolean(
com.android.internal.R.bool.config_pinnerCameraApp);
mPinnerHandler = new PinnerHandler(BackgroundThread.get().getLooper());
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
+ filter.addDataScheme("package");
+ mContext.registerReceiver(mBroadcastReceiver, filter);
}
@Override
@@ -85,6 +106,7 @@
}
mBinderService = new BinderService();
publishBinderService("pinner", mBinderService);
+ publishLocalService(PinnerService.class, this);
mPinnerHandler.obtainMessage(PinnerHandler.PIN_ONSTART_MSG).sendToTarget();
mPinnerHandler.obtainMessage(PinnerHandler.PIN_CAMERA_MSG, UserHandle.USER_SYSTEM, 0)
@@ -103,6 +125,17 @@
}
/**
+ * Update the currently pinned files.
+ * Specifically, this only updates camera pinning.
+ * The other files pinned in onStart will not need to be updated.
+ */
+ public void update() {
+ Slog.i(TAG, "Updating pinned files.");
+ mPinnerHandler.obtainMessage(PinnerHandler.PIN_CAMERA_MSG, UserHandle.USER_SYSTEM, 0)
+ .sendToTarget();
+ }
+
+ /**
* Handler for on start pinning message
*/
private void handlePinOnStart() {
@@ -202,13 +235,10 @@
return cameraResolveInfo.activityInfo.applicationInfo;
}
+ /**
+ * If the camera app is already pinned, unpin and repin it.
+ */
private boolean pinCamera(int userHandle){
- //we may have already pinned a camera app. If we've pinned this
- //camera app, we're done. otherwise, unpin and pin the new app
- if (alreadyPinned(userHandle)){
- return true;
- }
-
ApplicationInfo cameraInfo = getCameraInfo(userHandle);
if (cameraInfo == null) {
return false;
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 960351b..7ed07e0 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -957,7 +957,7 @@
// If we are not able to proceed, disassociate the activity from the task. Leaving an
// activity in an incomplete state can lead to issues, such as performing operations
// without a window container.
- if (ActivityManager.isStartResultFatalError(result)
+ if (!ActivityManager.isStartResultSuccessful(result)
&& mStartActivity.getTask() != null) {
mStartActivity.getTask().removeActivity(mStartActivity);
}
@@ -1051,6 +1051,15 @@
reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);
+ final ActivityRecord outResult =
+ outActivity != null && outActivity.length > 0 ? outActivity[0] : null;
+
+ // When there is a reused activity and the current result is a trampoline activity,
+ // set the reused activity as the result.
+ if (outResult != null && (outResult.finishing || outResult.noDisplay)) {
+ outActivity[0] = reusedActivity;
+ }
+
if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
// We don't need to start a new activity, and the client said not to do anything
// if that is the case, so this is it! And for paranoia, make sure we have
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 11fc40b..2439062 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -16,6 +16,8 @@
package com.android.server.am;
+import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_CPU;
+
import android.annotation.Nullable;
import android.bluetooth.BluetoothActivityEnergyInfo;
import android.bluetooth.BluetoothAdapter;
@@ -1549,7 +1551,9 @@
BatteryStats.HistoryItem.EVENT_COLLECT_EXTERNAL_STATS,
reason, 0);
- mStats.updateCpuTimeLocked();
+ if ((updateFlags & UPDATE_CPU) != 0) {
+ mStats.updateCpuTimeLocked(true /* updateCpuFreqData */);
+ }
mStats.updateKernelWakelocksLocked();
mStats.updateKernelMemoryBandwidthLocked();
diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java
index 069ae73..f804fa1c 100644
--- a/services/core/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/core/java/com/android/server/content/SyncStorageEngine.java
@@ -18,6 +18,7 @@
import android.accounts.Account;
import android.accounts.AccountAndUser;
+import android.accounts.AccountManager;
import android.app.backup.BackupManager;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -27,6 +28,7 @@
import android.content.SyncInfo;
import android.content.SyncRequest;
import android.content.SyncStatusInfo;
+import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
@@ -350,6 +352,50 @@
void onAuthorityRemoved(EndPoint removedAuthority);
}
+ /**
+ * Validator that maintains a lazy cache of accounts and providers to tell if an authority or
+ * account is valid.
+ */
+ private static class AccountAuthorityValidator {
+ final private AccountManager mAccountManager;
+ final private PackageManager mPackageManager;
+ final private SparseArray<Account[]> mAccountsCache;
+ final private SparseArray<ArrayMap<String, Boolean>> mProvidersPerUserCache;
+
+ AccountAuthorityValidator(Context context) {
+ mAccountManager = context.getSystemService(AccountManager.class);
+ mPackageManager = context.getPackageManager();
+ mAccountsCache = new SparseArray<>();
+ mProvidersPerUserCache = new SparseArray<>();
+ }
+
+ // An account is valid if an installed authenticator has previously created that account
+ // on the device
+ boolean isAccountValid(Account account, int userId) {
+ Account[] accountsForUser = mAccountsCache.get(userId);
+ if (accountsForUser == null) {
+ accountsForUser = mAccountManager.getAccountsAsUser(userId);
+ mAccountsCache.put(userId, accountsForUser);
+ }
+ return ArrayUtils.contains(accountsForUser, account);
+ }
+
+ // An authority is only valid if it has a content provider installed on the system
+ boolean isAuthorityValid(String authority, int userId) {
+ ArrayMap<String, Boolean> authorityMap = mProvidersPerUserCache.get(userId);
+ if (authorityMap == null) {
+ authorityMap = new ArrayMap<>();
+ mProvidersPerUserCache.put(userId, authorityMap);
+ }
+ if (!authorityMap.containsKey(authority)) {
+ authorityMap.put(authority, mPackageManager.resolveContentProviderAsUser(authority,
+ PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId) != null);
+ }
+ return authorityMap.get(authority);
+ }
+ }
+
// Primary list of all syncable authorities. Also our global lock.
private final SparseArray<AuthorityInfo> mAuthorities =
new SparseArray<AuthorityInfo>();
@@ -1502,12 +1548,13 @@
eventType = parser.next();
AuthorityInfo authority = null;
PeriodicSync periodicSync = null;
+ AccountAuthorityValidator validator = new AccountAuthorityValidator(mContext);
do {
if (eventType == XmlPullParser.START_TAG) {
tagName = parser.getName();
if (parser.getDepth() == 2) {
if ("authority".equals(tagName)) {
- authority = parseAuthority(parser, version);
+ authority = parseAuthority(parser, version, validator);
periodicSync = null;
if (authority != null) {
if (authority.ident > highestAuthorityId) {
@@ -1636,7 +1683,8 @@
mMasterSyncAutomatically.put(userId, listen);
}
- private AuthorityInfo parseAuthority(XmlPullParser parser, int version) {
+ private AuthorityInfo parseAuthority(XmlPullParser parser, int version,
+ AccountAuthorityValidator validator) {
AuthorityInfo authority = null;
int id = -1;
try {
@@ -1676,21 +1724,26 @@
if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
Slog.v(TAG_FILE, "Creating authority entry");
}
- EndPoint info = null;
if (accountName != null && authorityName != null) {
- info = new EndPoint(
+ EndPoint info = new EndPoint(
new Account(accountName, accountType),
authorityName, userId);
- }
- if (info != null) {
- authority = getOrCreateAuthorityLocked(info, id, false);
- // If the version is 0 then we are upgrading from a file format that did not
- // know about periodic syncs. In that case don't clear the list since we
- // want the default, which is a daily periodic sync.
- // Otherwise clear out this default list since we will populate it later with
- // the periodic sync descriptions that are read from the configuration file.
- if (version > 0) {
- authority.periodicSyncs.clear();
+ if (validator.isAccountValid(info.account, userId)
+ && validator.isAuthorityValid(authorityName, userId)) {
+ authority = getOrCreateAuthorityLocked(info, id, false);
+ // If the version is 0 then we are upgrading from a file format that did not
+ // know about periodic syncs. In that case don't clear the list since we
+ // want the default, which is a daily periodic sync.
+ // Otherwise clear out this default list since we will populate it later
+ // with
+ // the periodic sync descriptions that are read from the configuration file.
+ if (version > 0) {
+ authority.periodicSyncs.clear();
+ }
+ } else {
+ EventLog.writeEvent(0x534e4554, "35028827", -1,
+ "account:" + info.account + " provider:" + authorityName + " user:"
+ + userId);
}
}
}
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 85d8986..3fd91dc 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -937,9 +937,9 @@
long time = mNtpTime.getCachedNtpTime();
long timeReference = mNtpTime.getCachedNtpTimeReference();
long certainty = mNtpTime.getCacheCertainty();
- long now = SystemClock.elapsedRealtime();
if (DEBUG) {
+ long now = System.currentTimeMillis();
Log.d(TAG, "NTP server returned: "
+ time + " (" + new Date(time)
+ ") reference: " + timeReference
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 1ccd171..fc582b0 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1521,15 +1521,13 @@
final boolean isPackageSuspended =
isPackageSuspendedForUser(pkg, Binder.getCallingUid());
- if (ENABLE_BLOCKED_TOASTS && (!noteNotificationOp(pkg, Binder.getCallingUid())
- || isPackageSuspended)) {
- if (!isSystemToast) {
- Slog.e(TAG, "Suppressing toast from package " + pkg
- + (isPackageSuspended
- ? " due to package suspended by administrator."
- : " by user request."));
- return;
- }
+ if (ENABLE_BLOCKED_TOASTS && !isSystemToast &&
+ (!noteNotificationOp(pkg, Binder.getCallingUid()) || isPackageSuspended)) {
+ Slog.e(TAG, "Suppressing toast from package " + pkg
+ + (isPackageSuspended
+ ? " due to package suspended by administrator."
+ : " by user request."));
+ return;
}
synchronized (mToastQueue) {
@@ -3284,10 +3282,11 @@
}
private void doChannelWarningToast(CharSequence toastText) {
- final boolean warningEnabled = Settings.System.getInt(getContext().getContentResolver(),
+ final boolean warningEnabled = Settings.Global.getInt(getContext().getContentResolver(),
Settings.Global.SHOW_NOTIFICATION_CHANNEL_WARNINGS, 0) != 0;
if (warningEnabled || Build.IS_DEBUGGABLE) {
- Toast toast = Toast.makeText(getContext(), mHandler.getLooper(), toastText, Toast.LENGTH_LONG);
+ Toast toast = Toast.makeText(getContext(), mHandler.getLooper(), toastText,
+ Toast.LENGTH_LONG);
toast.show();
}
}
diff --git a/services/core/java/com/android/server/om/OverlayManagerSettings.java b/services/core/java/com/android/server/om/OverlayManagerSettings.java
index 353b710..c059b37 100644
--- a/services/core/java/com/android/server/om/OverlayManagerSettings.java
+++ b/services/core/java/com/android/server/om/OverlayManagerSettings.java
@@ -319,7 +319,7 @@
private static final String ATTR_USER_ID = "userId";
private static final String ATTR_VERSION = "version";
- private static final int CURRENT_VERSION = 2;
+ private static final int CURRENT_VERSION = 3;
public static void restore(@NonNull final ArrayList<SettingsItem> table,
@NonNull final InputStream is) throws IOException, XmlPullParserException {
@@ -350,6 +350,7 @@
switch (oldVersion) {
case 0:
case 1:
+ case 2:
// Throw an exception which will cause the overlay file to be ignored
// and overwritten.
throw new XmlPullParserException("old version " + oldVersion + "; ignoring");
diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
index d364d17..484cd4e 100644
--- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java
+++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
@@ -36,6 +36,8 @@
import android.util.Log;
import com.android.server.pm.dex.DexManager;
+import com.android.server.LocalServices;
+import com.android.server.PinnerService;
import java.io.File;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -366,11 +368,20 @@
return false;
}
+ boolean result;
if (params.getJobId() == JOB_POST_BOOT_UPDATE) {
- return runPostBootUpdate(params, pm, pkgs);
+ result = runPostBootUpdate(params, pm, pkgs);
} else {
- return runIdleOptimization(params, pm, pkgs);
+ result = runIdleOptimization(params, pm, pkgs);
}
+
+ PinnerService pinnerService = (PinnerService) LocalServices.getService(PinnerService.class);
+ if (pinnerService != null) {
+ Log.i(TAG, "Pinning optimized code");
+ pinnerService.update();
+ }
+
+ return result;
}
@Override
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index b1068ae..edf6dfc 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -20,7 +20,6 @@
import static android.Manifest.permission.INSTALL_PACKAGES;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.REQUEST_DELETE_PACKAGES;
-import static android.Manifest.permission.REQUEST_INSTALL_PACKAGES;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
@@ -100,7 +99,6 @@
import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
-
import static dalvik.system.DexFile.getNonProfileGuidedCompilerFilter;
import android.Manifest;
@@ -126,10 +124,8 @@
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.AppsQueryHelper;
-import android.content.pm.ChangedPackages;
-import android.content.pm.ComponentInfo;
-import android.content.pm.InstantAppRequest;
import android.content.pm.AuxiliaryResolveInfo;
+import android.content.pm.ChangedPackages;
import android.content.pm.FallbackCategoryProvider;
import android.content.pm.FeatureInfo;
import android.content.pm.IOnPermissionsChangeListener;
@@ -142,6 +138,7 @@
import android.content.pm.IPackageMoveObserver;
import android.content.pm.IPackageStatsObserver;
import android.content.pm.InstantAppInfo;
+import android.content.pm.InstantAppRequest;
import android.content.pm.InstantAppResolveInfo;
import android.content.pm.InstrumentationInfo;
import android.content.pm.IntentFilterVerificationInfo;
@@ -3086,16 +3083,19 @@
@Override
public boolean isFirstBoot() {
+ // allow instant applications
return mFirstBoot;
}
@Override
public boolean isOnlyCoreApps() {
+ // allow instant applications
return mOnlyCore;
}
@Override
public boolean isUpgrade() {
+ // allow instant applications
return mIsUpgrade;
}
@@ -3189,6 +3189,9 @@
@Override
public @Nullable ComponentName getInstantAppResolverComponent() {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return null;
+ }
synchronized (mPackages) {
final Pair<ComponentName, String> instantAppResolver = getInstantAppResolverLPr();
if (instantAppResolver == null) {
@@ -3576,8 +3579,10 @@
@Override
public void checkPackageStartable(String packageName, int userId) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ throw new SecurityException("Instant applications don't have access to this method");
+ }
final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
-
synchronized (mPackages) {
final PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps == null) {
@@ -3797,6 +3802,9 @@
@Override
public String[] currentToCanonicalPackageNames(String[] names) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return names;
+ }
String[] out = new String[names.length];
// reader
synchronized (mPackages) {
@@ -3810,6 +3818,9 @@
@Override
public String[] canonicalToCurrentPackageNames(String[] names) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return names;
+ }
String[] out = new String[names.length];
// reader
synchronized (mPackages) {
@@ -3887,6 +3898,9 @@
@Override
public PermissionInfo getPermissionInfo(String name, int flags) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return null;
+ }
// reader
synchronized (mPackages) {
final BasePermission p = mSettings.mPermissions.get(name);
@@ -3900,6 +3914,9 @@
@Override
public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
int flags) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return null;
+ }
// reader
synchronized (mPackages) {
if (group != null && !mPermissionGroups.containsKey(group)) {
@@ -3925,6 +3942,9 @@
@Override
public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return null;
+ }
// reader
synchronized (mPackages) {
return PackageParser.generatePermissionGroupInfo(
@@ -3934,6 +3954,9 @@
@Override
public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return ParceledListSlice.emptyList();
+ }
// reader
synchronized (mPackages) {
final int N = mPermissionGroups.size();
@@ -4428,6 +4451,9 @@
int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return null;
+ }
flags = updateFlagsForPackage(flags, userId, null);
@@ -4638,6 +4664,7 @@
@Override
public @NonNull String getServicesSystemSharedLibraryPackageName() {
+ // allow instant applications
synchronized (mPackages) {
return mServicesSystemSharedLibraryPackageName;
}
@@ -4645,6 +4672,7 @@
@Override
public @NonNull String getSharedSystemSharedLibraryPackageName() {
+ // allow instant applications
synchronized (mPackages) {
return mSharedSystemSharedLibraryPackageName;
}
@@ -4675,6 +4703,9 @@
@Override
public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return null;
+ }
synchronized (mPackages) {
if (sequenceNumber >= mChangedPackagesSequenceNumber) {
return null;
@@ -4698,6 +4729,7 @@
@Override
public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
+ // allow instant applications
ArrayList<FeatureInfo> res;
synchronized (mAvailableFeatures) {
res = new ArrayList<>(mAvailableFeatures.size() + 1);
@@ -4713,6 +4745,7 @@
@Override
public boolean hasSystemFeature(String name, int version) {
+ // allow instant applications
synchronized (mAvailableFeatures) {
final FeatureInfo feat = mAvailableFeatures.get(name);
if (feat == null) {
@@ -4810,6 +4843,9 @@
@Override
public String getPermissionControllerPackageName() {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ throw new SecurityException("Instant applications don't have access to this method");
+ }
synchronized (mPackages) {
return mRequiredInstallerPackage;
}
@@ -4944,6 +4980,9 @@
}
boolean addPermissionLocked(PermissionInfo info, boolean async) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ throw new SecurityException("Instant apps can't add permissions");
+ }
if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
throw new SecurityException("Label must be specified in permission");
}
@@ -5003,6 +5042,9 @@
@Override
public void removePermission(String name) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ throw new SecurityException("Instant applications don't have access to this method");
+ }
synchronized (mPackages) {
checkPermissionTreeLP(name);
BasePermission bp = mSettings.mPermissions.get(name);
@@ -5018,8 +5060,8 @@
}
}
- private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg,
- BasePermission bp) {
+ private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(
+ PackageParser.Package pkg, BasePermission bp) {
int index = pkg.requestedPermissions.indexOf(bp.name);
if (index == -1) {
throw new SecurityException("Package " + pkg.packageName
@@ -5536,6 +5578,9 @@
@Override
public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ throw new SecurityException("Instant applications don't have access to this method");
+ }
synchronized (mPackages) {
mOnPermissionChangeListeners.removeListenerLocked(listener);
}
@@ -5543,6 +5588,7 @@
@Override
public boolean isProtectedBroadcast(String actionName) {
+ // allow instant applications
synchronized (mPackages) {
if (mProtectedBroadcasts.contains(actionName)) {
return true;
@@ -5819,6 +5865,9 @@
@Override
public int getUidForSharedUser(String sharedUserName) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return -1;
+ }
if(sharedUserName == null) {
return -1;
}
@@ -5839,6 +5888,9 @@
@Override
public int getFlagsForUid(int uid) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return 0;
+ }
synchronized (mPackages) {
Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
if (obj instanceof SharedUserSetting) {
@@ -5854,6 +5906,9 @@
@Override
public int getPrivateFlagsForUid(int uid) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return 0;
+ }
synchronized (mPackages) {
Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
if (obj instanceof SharedUserSetting) {
@@ -5869,6 +5924,9 @@
@Override
public boolean isUidPrivileged(int uid) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return false;
+ }
uid = UserHandle.getAppId(uid);
// reader
synchronized (mPackages) {
@@ -5891,6 +5949,9 @@
@Override
public String[] getAppOpPermissionPackages(String permissionName) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return null;
+ }
synchronized (mPackages) {
ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
if (pkgs == null) {
@@ -5956,6 +6017,9 @@
@Override
public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
IntentFilter filter, int match, ComponentName activity) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return;
+ }
final int userId = UserHandle.getCallingUserId();
if (DEBUG_PREFERRED) {
Log.v(TAG, "setLastChosenActivity intent=" + intent
@@ -5979,6 +6043,9 @@
@Override
public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return null;
+ }
final int userId = UserHandle.getCallingUserId();
if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
@@ -6440,12 +6507,12 @@
* instant, returns {@code null}.
*/
private String getInstantAppPackageName(int callingUid) {
- // If the caller is an isolated app use the owner's uid for the lookup.
- if (Process.isIsolated(callingUid)) {
- callingUid = mIsolatedOwners.get(callingUid);
- }
- final int appId = UserHandle.getAppId(callingUid);
synchronized (mPackages) {
+ // If the caller is an isolated app use the owner's uid for the lookup.
+ if (Process.isIsolated(callingUid)) {
+ callingUid = mIsolatedOwners.get(callingUid);
+ }
+ final int appId = UserHandle.getAppId(callingUid);
final Object obj = mSettings.getUserIdLPr(appId);
if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
@@ -7662,6 +7729,9 @@
@Override
public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return ParceledListSlice.emptyList();
+ }
if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
flags = updateFlagsForPackage(flags, userId, null);
final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
@@ -7776,6 +7846,9 @@
@Override
public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return ParceledListSlice.emptyList();
+ }
if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
flags = updateFlagsForApplication(flags, userId, null);
final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
@@ -7839,7 +7912,6 @@
if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
return null;
}
-
mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
"getEphemeralApplications");
enforceCrossUserPermission(Binder.getCallingUid(), userId,
@@ -7863,9 +7935,9 @@
if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
return false;
}
- int uid = Binder.getCallingUid();
- if (Process.isIsolated(uid)) {
- uid = mIsolatedOwners.get(uid);
+ int callingUid = Binder.getCallingUid();
+ if (Process.isIsolated(callingUid)) {
+ callingUid = mIsolatedOwners.get(callingUid);
}
synchronized (mPackages) {
@@ -7873,12 +7945,12 @@
PackageParser.Package pkg = mPackages.get(packageName);
final boolean returnAllowed =
ps != null
- && (isCallerSameApp(packageName, uid)
+ && (isCallerSameApp(packageName, callingUid)
|| mContext.checkCallingOrSelfPermission(
android.Manifest.permission.ACCESS_INSTANT_APPS)
== PERMISSION_GRANTED
|| mInstantAppRegistry.isInstantAccessGranted(
- userId, UserHandle.getAppId(uid), ps.appId));
+ userId, UserHandle.getAppId(callingUid), ps.appId));
if (returnAllowed) {
return ps.getInstantApp(userId);
}
@@ -7949,6 +8021,9 @@
@Override
public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return ParceledListSlice.emptyList();
+ }
return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
}
@@ -8032,6 +8107,9 @@
*/
@Deprecated
public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return;
+ }
// reader
synchronized (mPackages) {
final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
@@ -8727,7 +8805,7 @@
*/
private static final void enforceSystemOrRoot(String message) {
final int uid = Binder.getCallingUid();
- if (uid != Process.SYSTEM_UID && uid != 0) {
+ if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) {
throw new SecurityException(message);
}
}
@@ -8933,6 +9011,9 @@
@Override
public boolean performDexOptMode(String packageName,
boolean checkProfiles, String targetCompilerFilter, boolean force) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return false;
+ }
int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
targetCompilerFilter, force);
return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
@@ -9026,6 +9107,9 @@
@Override
public boolean performDexOptSecondary(String packageName, String compilerFilter,
boolean force) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return false;
+ }
mDexManager.reconcileSecondaryDexFiles(packageName);
return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force);
}
@@ -9042,6 +9126,9 @@
*/
@Override
public void reconcileSecondaryDexFiles(String packageName) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return;
+ }
mDexManager.reconcileSecondaryDexFiles(packageName);
}
@@ -9056,6 +9143,9 @@
*/
@Override
public boolean runBackgroundDexoptJob() {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return false;
+ }
return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext);
}
@@ -13509,6 +13599,9 @@
@Override
public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return null;
+ }
// writer
synchronized (mPackages) {
if (!isExternalMediaAvailable()) {
@@ -14423,6 +14516,9 @@
@Override
public int getIntentVerificationStatus(String packageName, int userId) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
+ }
synchronized (mPackages) {
return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
}
@@ -14446,6 +14542,9 @@
@Override
public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
String packageName) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return ParceledListSlice.emptyList();
+ }
synchronized (mPackages) {
return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
}
@@ -14490,6 +14589,9 @@
@Override
public String getDefaultBrowserPackageName(int userId) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return null;
+ }
synchronized (mPackages) {
return mSettings.getDefaultBrowserPackageNameLPw(userId);
}
@@ -14508,7 +14610,10 @@
@Override
public void setInstallerPackageName(String targetPackage, String installerPackageName) {
- final int uid = Binder.getCallingUid();
+ final int callingUid = Binder.getCallingUid();
+ if (getInstantAppPackageName(callingUid) != null) {
+ return;
+ }
// writer
synchronized (mPackages) {
PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
@@ -14528,17 +14633,17 @@
}
Signature[] callerSignature;
- Object obj = mSettings.getUserIdLPr(uid);
+ Object obj = mSettings.getUserIdLPr(callingUid);
if (obj != null) {
if (obj instanceof SharedUserSetting) {
callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
} else if (obj instanceof PackageSetting) {
callerSignature = ((PackageSetting)obj).signatures.mSignatures;
} else {
- throw new SecurityException("Bad object " + obj + " for uid " + uid);
+ throw new SecurityException("Bad object " + obj + " for uid " + callingUid);
}
} else {
- throw new SecurityException("Unknown calling UID: " + uid);
+ throw new SecurityException("Unknown calling UID: " + callingUid);
}
// Verify: can't set installerPackageName to a package that is
@@ -14583,6 +14688,9 @@
@Override
public void setApplicationCategoryHint(String packageName, int categoryHint,
String callerPackageName) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ throw new SecurityException("Instant applications don't have access to this method");
+ }
mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
callerPackageName);
synchronized (mPackages) {
@@ -16592,9 +16700,13 @@
}
}
+ @Override
public List<String> getPreviousCodePaths(String packageName) {
+ final List<String> result = new ArrayList<>();
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return result;
+ }
final PackageSetting ps = mSettings.mPackages.get(packageName);
- final List<String> result = new ArrayList<String>();
if (ps != null && ps.oldCodePaths != null) {
result.addAll(ps.oldCodePaths);
}
@@ -18719,11 +18831,7 @@
@Override
public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
- int callingUid = Binder.getCallingUid();
- if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
- throw new SecurityException(
- "setRequiredForSystemUser can only be run by the system or root");
- }
+ enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
synchronized (mPackages) {
PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps == null) {
@@ -19577,18 +19685,21 @@
@Override
public void clearPackagePreferredActivities(String packageName) {
- final int uid = Binder.getCallingUid();
+ final int callingUid = Binder.getCallingUid();
+ if (getInstantAppPackageName(callingUid) != null) {
+ return;
+ }
// writer
synchronized (mPackages) {
PackageParser.Package pkg = mPackages.get(packageName);
- if (pkg == null || pkg.applicationInfo.uid != uid) {
+ if (pkg == null || pkg.applicationInfo.uid != callingUid) {
if (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
!= PackageManager.PERMISSION_GRANTED) {
- if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
+ if (getUidTargetSdkVersionLockedLPr(callingUid)
< Build.VERSION_CODES.FROYO) {
Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
- + Binder.getCallingUid());
+ + callingUid);
return;
}
mContext.enforceCallingOrSelfPermission(
@@ -19711,7 +19822,9 @@
@Override
public int getPreferredActivities(List<IntentFilter> outFilters,
List<ComponentName> outActivities, String packageName) {
-
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return 0;
+ }
int num = 0;
final int userId = UserHandle.getCallingUserId();
// reader
@@ -20280,6 +20393,9 @@
@Override
public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return null;
+ }
return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
}
@@ -20364,6 +20480,9 @@
@Override
public void setHomeActivity(ComponentName comp, int userId) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return;
+ }
ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
getHomeActivitiesAsUser(homeActivities, userId);
@@ -20461,43 +20580,58 @@
+ newState);
}
PackageSetting pkgSetting;
- final int uid = Binder.getCallingUid();
+ final int callingUid = Binder.getCallingUid();
final int permission;
- if (uid == Process.SYSTEM_UID) {
+ if (callingUid == Process.SYSTEM_UID) {
permission = PackageManager.PERMISSION_GRANTED;
} else {
permission = mContext.checkCallingOrSelfPermission(
android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
}
- enforceCrossUserPermission(uid, userId,
+ enforceCrossUserPermission(callingUid, userId,
false /* requireFullPermission */, true /* checkShell */, "set enabled");
final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
boolean sendNow = false;
boolean isApp = (className == null);
+ final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);
String componentName = isApp ? packageName : className;
int packageUid = -1;
ArrayList<String> components;
- // writer
+ // reader
synchronized (mPackages) {
pkgSetting = mSettings.mPackages.get(packageName);
if (pkgSetting == null) {
- if (className == null) {
- throw new IllegalArgumentException("Unknown package: " + packageName);
+ if (!isCallerInstantApp) {
+ if (className == null) {
+ throw new IllegalArgumentException("Unknown package: " + packageName);
+ }
+ throw new IllegalArgumentException(
+ "Unknown component: " + packageName + "/" + className);
+ } else {
+ // throw SecurityException to prevent leaking package information
+ throw new SecurityException(
+ "Attempt to change component state; "
+ + "pid=" + Binder.getCallingPid()
+ + ", uid=" + callingUid
+ + (className == null
+ ? ", package=" + packageName
+ : ", component=" + packageName + "/" + className));
}
- throw new IllegalArgumentException(
- "Unknown component: " + packageName + "/" + className);
}
}
// Limit who can change which apps
- if (!UserHandle.isSameApp(uid, pkgSetting.appId)) {
+ if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
// Don't allow apps that don't have permission to modify other apps
if (!allowedByPermission) {
throw new SecurityException(
- "Permission Denial: attempt to change component state from pid="
- + Binder.getCallingPid()
- + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
+ "Attempt to change component state; "
+ + "pid=" + Binder.getCallingPid()
+ + ", uid=" + callingUid
+ + (className == null
+ ? ", package=" + packageName
+ : ", component=" + packageName + "/" + className));
}
// Don't allow changing protected packages.
if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
@@ -20506,7 +20640,7 @@
}
synchronized (mPackages) {
- if (uid == Process.SHELL_UID
+ if (callingUid == Process.SHELL_UID
&& (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
// Shell can only change whole packages between ENABLED and DISABLED_USER states
// unless it is a test package.
@@ -20622,6 +20756,9 @@
@Override
public void flushPackageRestrictionsAsUser(int userId) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return;
+ }
if (!sUserManager.exists(userId)) {
return;
}
@@ -20660,16 +20797,19 @@
@Override
public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
if (!sUserManager.exists(userId)) return;
- final int uid = Binder.getCallingUid();
+ final int callingUid = Binder.getCallingUid();
+ if (getInstantAppPackageName(callingUid) != null) {
+ return;
+ }
final int permission = mContext.checkCallingOrSelfPermission(
android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
- enforceCrossUserPermission(uid, userId,
+ enforceCrossUserPermission(callingUid, userId,
true /* requireFullPermission */, true /* checkShell */, "stop package");
// writer
synchronized (mPackages) {
if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
- allowedByPermission, uid, userId)) {
+ allowedByPermission, callingUid, userId)) {
scheduleWritePackageRestrictionsLocked(userId);
}
}
@@ -20677,6 +20817,9 @@
@Override
public String getInstallerPackageName(String packageName) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return null;
+ }
// reader
synchronized (mPackages) {
return mSettings.getInstallerPackageNameLPr(packageName);
@@ -20725,6 +20868,8 @@
@Override
public void systemReady() {
+ enforceSystemOrRoot("Only the system can claim the system is ready");
+
mSystemReady = true;
final ContentResolver resolver = mContext.getContentResolver();
ContentObserver co = new ContentObserver(mHandler) {
@@ -20872,11 +21017,13 @@
@Override
public boolean isSafeMode() {
+ // allow instant applications
return mSafeMode;
}
@Override
public boolean hasSystemUidErrors() {
+ // allow instant applications
return mHasSystemUidErrors;
}
@@ -21838,10 +21985,7 @@
*/
@Override
public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
- int callingUid = Binder.getCallingUid();
- if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
- throw new SecurityException("Media status can only be updated by the system");
- }
+ enforceSystemOrRoot("Media status can only be updated by the system");
// reader; this apparently protects mMediaMounted, but should probably
// be a different lock in that case.
synchronized (mPackages) {
@@ -23173,6 +23317,7 @@
@Override
public int getInstallLocation() {
+ // allow instant app access
return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
PackageHelper.APP_INSTALL_AUTO);
@@ -23313,11 +23458,13 @@
@Override
@Deprecated
public boolean isPermissionEnforced(String permission) {
+ // allow instant applications
return true;
}
@Override
public boolean isStorageLow() {
+ // allow instant applications
final long token = Binder.clearCallingIdentity();
try {
final DeviceStorageMonitorInternal
@@ -23334,6 +23481,9 @@
@Override
public IPackageInstaller getPackageInstaller() {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return null;
+ }
return mInstallerService;
}
@@ -23397,6 +23547,9 @@
@Override
public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return false;
+ }
if (packageName == null || ks == null) {
return false;
}
@@ -23417,6 +23570,9 @@
@Override
public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return false;
+ }
if (packageName == null || ks == null) {
return false;
}
@@ -24015,8 +24171,12 @@
* Logs process start information (including base APK hash) to the security log.
* @hide
*/
+ @Override
public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
String apkFile, int pid) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return;
+ }
if (!SecurityLog.isLoggingEnabled()) {
return;
}
@@ -24065,6 +24225,9 @@
@Override
public boolean canRequestPackageInstalls(String packageName, int userId) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return false;
+ }
return canRequestPackageInstallsInternal(packageName, 0, userId,
true /* throwIfPermNotDeclared*/);
}
@@ -24115,6 +24278,9 @@
@Override
public ComponentName getInstantAppInstallerComponent() {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return null;
+ }
return mInstantAppInstallerActivity == null
? null : mInstantAppInstallerActivity.getComponentName();
}
diff --git a/services/core/java/com/android/server/wm/AlertWindowNotification.java b/services/core/java/com/android/server/wm/AlertWindowNotification.java
index 50b1520..7ed3eac 100644
--- a/services/core/java/com/android/server/wm/AlertWindowNotification.java
+++ b/services/core/java/com/android/server/wm/AlertWindowNotification.java
@@ -16,14 +16,15 @@
package com.android.server.wm;
+import static android.app.NotificationManager.IMPORTANCE_MIN;
import static android.app.PendingIntent.FLAG_CANCEL_CURRENT;
import static android.content.Context.NOTIFICATION_SERVICE;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.provider.Settings.ACTION_MANAGE_OVERLAY_PERMISSION;
-import static com.android.internal.notification.SystemNotificationChannels.ALERT_WINDOW;
import android.app.Notification;
+import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
@@ -40,7 +41,7 @@
/** Displays an ongoing notification for a process displaying an alert window */
class AlertWindowNotification {
- private static final String TAG_PREFIX = "com.android.server.wm.AlertWindowNotification: ";
+ private static final String CHANNEL_PREFIX = "com.android.server.wm.AlertWindowNotification - ";
private static final int NOTIFICATION_ID = 0;
private static int sNextRequestCode = 0;
@@ -57,7 +58,7 @@
mPackageName = packageName;
mNotificationManager =
(NotificationManager) mService.mContext.getSystemService(NOTIFICATION_SERVICE);
- mNotificationTag = TAG_PREFIX + mPackageName;
+ mNotificationTag = CHANNEL_PREFIX + mPackageName;
mRequestCode = sNextRequestCode++;
mIconUtilities = new IconUtilities(mService.mContext);
}
@@ -99,9 +100,11 @@
final String appName = (aInfo != null)
? pm.getApplicationLabel(aInfo).toString() : mPackageName;
+ createNotificationChannelIfNeeded(context, appName);
+
final String message = context.getString(R.string.alert_windows_notification_message,
appName);
- final Notification.Builder builder = new Notification.Builder(context, ALERT_WINDOW)
+ final Notification.Builder builder = new Notification.Builder(context, mNotificationTag)
.setOngoing(true)
.setContentTitle(
context.getString(R.string.alert_windows_notification_title, appName))
@@ -131,6 +134,20 @@
return PendingIntent.getActivity(context, mRequestCode, intent, FLAG_CANCEL_CURRENT);
}
+ private void createNotificationChannelIfNeeded(Context context, String appName) {
+ if (mNotificationManager.getNotificationChannel(mNotificationTag) != null) {
+ return;
+ }
+ final String nameChannel =
+ context.getString(R.string.alert_windows_notification_channel_name, appName);
+ final NotificationChannel channel =
+ new NotificationChannel(mNotificationTag, nameChannel, IMPORTANCE_MIN);
+ channel.enableLights(false);
+ channel.enableVibration(false);
+ mNotificationManager.createNotificationChannel(channel);
+ }
+
+
private ApplicationInfo getApplicationInfo(PackageManager pm, String packageName) {
try {
return pm.getApplicationInfo(packageName, 0);
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index e300256..2d7fc68 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -191,12 +191,16 @@
mTmpRect);
int dividerSize = mDividerWindowWidth - 2 * mDividerInsets;
Configuration configuration = mDisplayContent.getConfiguration();
+ // The offset in the left (landscape)/top (portrait) is calculated with the minimized
+ // offset value with the divider size and any system insets in that direction.
if (configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
outBounds.set(0, mTaskHeightInMinimizedMode + dividerSize + mTmpRect.top,
di.logicalWidth, di.logicalHeight);
} else {
- outBounds.set(mTaskHeightInMinimizedMode + dividerSize + mTmpRect.left, 0,
- di.logicalWidth, di.logicalHeight);
+ // In landscape append the left position with the statusbar height to match the
+ // minimized size height in portrait mode.
+ outBounds.set(mTaskHeightInMinimizedMode + dividerSize + mTmpRect.left + mTmpRect.top,
+ 0, di.logicalWidth, di.logicalHeight);
}
}
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index e576f2f..4a1a705 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -15,6 +15,7 @@
import static com.android.server.wm.AppTransition.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
import static com.android.server.wm.AppTransition.TRANSIT_KEYGUARD_GOING_AWAY;
import static com.android.server.wm.AppTransition.TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
+import static com.android.server.wm.AppTransition.TRANSIT_NONE;
import static com.android.server.wm.AppTransition.TRANSIT_TASK_CLOSE;
import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
@@ -580,6 +581,11 @@
private int maybeUpdateTransitToWallpaper(int transit, boolean openingAppHasWallpaper,
boolean closingAppHasWallpaper) {
+ // Given no app transition pass it through instead of a wallpaper transition
+ if (transit == TRANSIT_NONE) {
+ return TRANSIT_NONE;
+ }
+
// if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
final WindowState oldWallpaper = mWallpaperControllerLocked.isWallpaperTargetAnimating()
diff --git a/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java b/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java
index 19defe1..2f202d98 100644
--- a/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java
@@ -36,6 +36,7 @@
import org.junit.Before;
import org.junit.BeforeClass;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -58,6 +59,7 @@
* Run: adb shell am instrument -e class com.android.server.am.CoreSettingsObserverTest -w \
* com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
*/
+@Ignore
@SmallTest
@RunWith(AndroidJUnit4.class)
public class CoreSettingsObserverTest {
diff --git a/services/tests/servicestests/src/com/android/server/net/ConnOnActivityStartTest.java b/services/tests/servicestests/src/com/android/server/net/ConnOnActivityStartTest.java
index 9014539..f02cf51 100644
--- a/services/tests/servicestests/src/com/android/server/net/ConnOnActivityStartTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/ConnOnActivityStartTest.java
@@ -54,6 +54,7 @@
import org.junit.AfterClass;
import org.junit.BeforeClass;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -78,6 +79,7 @@
* Run: adb shell am instrument -e class com.android.server.net.ConnOnActivityStartTest -w \
* com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
*/
+@Ignore
@LargeTest
@RunWith(AndroidJUnit4.class)
public class ConnOnActivityStartTest {
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 0a67669..26a406f 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -63,7 +63,6 @@
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
-import java.util.Random;
import java.util.Scanner;
import java.util.Set;
@@ -538,7 +537,6 @@
oldFunctions = UsbManager.USB_FUNCTION_NONE;
}
- Slog.i(TAG, "Setting adb to " + String.valueOf(enable));
setEnabledFunctions(oldFunctions, true, mUsbDataUnlocked);
updateAdbNotification();
}
@@ -766,16 +764,15 @@
// send broadcast intent only if the USB state has changed
if (!isUsbStateChanged(intent)) {
- Slog.i(TAG, "skip broadcasting " + intent + " extras: " + intent.getExtras());
+ if (DEBUG) {
+ Slog.d(TAG, "skip broadcasting " + intent + " extras: " + intent.getExtras());
+ }
return;
}
- mBroadcastedIntent = intent;
- Random rand = new Random();
- intent.putExtra("random_tag", rand.nextInt(1000));
- Slog.i(TAG, "broadcasting " + intent + " extras: " + intent.getExtras());
+ if (DEBUG) Slog.d(TAG, "broadcasting " + intent + " extras: " + intent.getExtras());
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
- intent.removeExtra("random_tag");
+ mBroadcastedIntent = intent;
}
private void updateUsbFunctions() {
@@ -844,7 +841,6 @@
updateUsbNotification();
updateAdbNotification();
if (mBootCompleted) {
- Slog.i(TAG, "update state " + mConnected + " " + mConfigured);
updateUsbStateBroadcastIfNeeded(false);
}
if (UsbManager.containsFunction(mCurrentFunctions,
@@ -854,7 +850,6 @@
if (mBootCompleted) {
if (!mConnected) {
// restore defaults when USB is disconnected
- Slog.i(TAG, "Disconnect, setting usb functions to null");
setEnabledFunctions(null, !mAdbEnabled, false);
}
updateUsbFunctions();
@@ -887,7 +882,6 @@
break;
case MSG_SET_CURRENT_FUNCTIONS:
String functions = (String) msg.obj;
- Slog.i(TAG, "Getting setFunction command for " + functions);
setEnabledFunctions(functions, false, msg.arg1 == 1);
break;
case MSG_UPDATE_USER_RESTRICTIONS:
@@ -895,8 +889,6 @@
final boolean forceRestart = mUsbDataUnlocked
&& isUsbDataTransferActive()
&& !isUsbTransferAllowed();
- Slog.i(TAG, "Updating user restrictions, force restart is "
- + String.valueOf(forceRestart));
setEnabledFunctions(
mCurrentFunctions, forceRestart, mUsbDataUnlocked && !forceRestart);
break;
@@ -911,7 +903,6 @@
updateUsbStateBroadcastIfNeeded(false);
mPendingBootBroadcast = false;
}
- Slog.i(TAG, "Boot complete, setting default functions");
setEnabledFunctions(null, false, false);
if (mCurrentAccessory != null) {
getCurrentSettings().accessoryAttached(mCurrentAccessory);
@@ -929,7 +920,6 @@
Slog.v(TAG, "Current user switched to " + msg.arg1
+ "; resetting USB host stack for MTP or PTP");
// avoid leaking sensitive data from previous user
- Slog.i(TAG, "User Switched, kicking usb stack");
setEnabledFunctions(mCurrentFunctions, true, false);
}
mCurrentUser = msg.arg1;
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index d942d05..088cbc6 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -131,7 +131,7 @@
boolean stopSoftAp();
- int startLocalOnlyHotspot(in Messenger messenger, in IBinder binder);
+ int startLocalOnlyHotspot(in Messenger messenger, in IBinder binder, in String packageName);
void stopLocalOnlyHotspot();
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index cda078a..25d61af 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -1899,7 +1899,9 @@
LocalOnlyHotspotCallbackProxy proxy =
new LocalOnlyHotspotCallbackProxy(this, looper, callback);
try {
- int returnCode = mService.startLocalOnlyHotspot(proxy.getMessenger(), new Binder());
+ String packageName = mContext.getOpPackageName();
+ int returnCode = mService.startLocalOnlyHotspot(
+ proxy.getMessenger(), new Binder(), packageName);
if (returnCode != LocalOnlyHotspotCallback.REQUEST_REGISTERED) {
// Send message to the proxy to make sure we call back on the correct thread
proxy.notifyFailed(returnCode);
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
index adf897d..84ac118 100644
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
@@ -58,6 +58,7 @@
private static final int ERROR_NOT_SET = -1;
private static final int ERROR_TEST_REASON = 5;
+ private static final String TEST_PACKAGE_NAME = "TestPackage";
@Mock Context mContext;
@Mock IWifiManager mWifiService;
@@ -76,6 +77,7 @@
mLooper = new TestLooper();
mHandler = spy(new Handler(mLooper.getLooper()));
when(mContext.getApplicationInfo()).thenReturn(mApplicationInfo);
+ when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME);
mWifiServiceMessenger = new Messenger(mHandler);
mWifiManager = new WifiManager(mContext, mWifiService, mLooper.getLooper());
@@ -126,8 +128,8 @@
@Test
public void testCreationAndCloseOfLocalOnlyHotspotReservation() throws Exception {
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
- .thenReturn(REQUEST_REGISTERED);
+ when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+ anyString())).thenReturn(REQUEST_REGISTERED);
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(mApConfig));
@@ -144,8 +146,8 @@
public void testLocalOnlyHotspotReservationCallsStopProperlyInTryWithResources()
throws Exception {
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
- .thenReturn(REQUEST_REGISTERED);
+ when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+ anyString())).thenReturn(REQUEST_REGISTERED);
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(mApConfig));
@@ -304,7 +306,8 @@
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
- verify(mWifiService).startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class));
+ verify(mWifiService)
+ .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString());
}
/**
@@ -315,7 +318,7 @@
public void testStartLocalOnlyHotspotThrowsSecurityException() throws Exception {
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
doThrow(new SecurityException()).when(mWifiService)
- .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class));
+ .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString());
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
}
@@ -327,7 +330,7 @@
public void testStartLocalOnlyHotspotThrowsIllegalStateException() throws Exception {
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
doThrow(new IllegalStateException()).when(mWifiService)
- .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class));
+ .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString());
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
}
@@ -337,8 +340,8 @@
@Test
public void testCorrectLooperIsUsedForHandler() throws Exception {
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
- .thenReturn(ERROR_INCOMPATIBLE_MODE);
+ when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+ anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE);
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
mLooper.dispatchAll();
assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
@@ -355,8 +358,8 @@
TestLooper altLooper = new TestLooper();
when(mContext.getMainLooper()).thenReturn(altLooper.getLooper());
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
- .thenReturn(ERROR_INCOMPATIBLE_MODE);
+ when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+ anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE);
mWifiManager.startLocalOnlyHotspot(callback, null);
altLooper.dispatchAll();
assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
@@ -374,7 +377,7 @@
TestLooper callbackLooper = new TestLooper();
Handler callbackHandler = new Handler(callbackLooper.getLooper());
when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(),
- any(IBinder.class))).thenReturn(REQUEST_REGISTERED);
+ any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED);
mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
callbackLooper.dispatchAll();
mLooper.dispatchAll();
@@ -401,7 +404,7 @@
TestLooper callbackLooper = new TestLooper();
Handler callbackHandler = new Handler(callbackLooper.getLooper());
when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(),
- any(IBinder.class))).thenReturn(REQUEST_REGISTERED);
+ any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED);
mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
callbackLooper.dispatchAll();
mLooper.dispatchAll();
@@ -426,7 +429,7 @@
TestLooper callbackLooper = new TestLooper();
Handler callbackHandler = new Handler(callbackLooper.getLooper());
when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(),
- any(IBinder.class))).thenReturn(REQUEST_REGISTERED);
+ any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED);
mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
callbackLooper.dispatchAll();
mLooper.dispatchAll();
@@ -449,7 +452,7 @@
TestLooper callbackLooper = new TestLooper();
Handler callbackHandler = new Handler(callbackLooper.getLooper());
when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(),
- any(IBinder.class))).thenReturn(REQUEST_REGISTERED);
+ any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED);
mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
callbackLooper.dispatchAll();
mLooper.dispatchAll();
@@ -470,8 +473,8 @@
@Test
public void testLocalOnlyHotspotCallbackFullOnIncompatibleMode() throws Exception {
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
- .thenReturn(ERROR_INCOMPATIBLE_MODE);
+ when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+ anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE);
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
mLooper.dispatchAll();
assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
@@ -486,8 +489,8 @@
@Test
public void testLocalOnlyHotspotCallbackFullOnTetheringDisallowed() throws Exception {
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
- .thenReturn(ERROR_TETHERING_DISALLOWED);
+ when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+ anyString())).thenReturn(ERROR_TETHERING_DISALLOWED);
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
mLooper.dispatchAll();
assertEquals(ERROR_TETHERING_DISALLOWED, callback.mFailureReason);
@@ -504,7 +507,7 @@
public void testLocalOnlyHotspotCallbackFullOnSecurityException() throws Exception {
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
doThrow(new SecurityException()).when(mWifiService)
- .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class));
+ .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString());
try {
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
} catch (SecurityException e) {
@@ -524,8 +527,8 @@
@Test
public void testLocalOnlyHotspotCallbackFullOnNoChannelError() throws Exception {
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
- .thenReturn(REQUEST_REGISTERED);
+ when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+ anyString())).thenReturn(REQUEST_REGISTERED);
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
mLooper.dispatchAll();
//assertEquals(ERROR_NO_CHANNEL, callback.mFailureReason);
@@ -540,8 +543,8 @@
@Test
public void testCancelLocalOnlyHotspotRequestCallsStopOnWifiService() throws Exception {
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
- .thenReturn(REQUEST_REGISTERED);
+ when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+ anyString())).thenReturn(REQUEST_REGISTERED);
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
mWifiManager.cancelLocalOnlyHotspotRequest();
verify(mWifiService).stopLocalOnlyHotspot();
@@ -562,8 +565,8 @@
@Test
public void testCallbackAfterLocalOnlyHotspotWasCancelled() throws Exception {
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
- .thenReturn(REQUEST_REGISTERED);
+ when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+ anyString())).thenReturn(REQUEST_REGISTERED);
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
mWifiManager.cancelLocalOnlyHotspotRequest();
verify(mWifiService).stopLocalOnlyHotspot();
@@ -581,8 +584,8 @@
@Test
public void testCancelAfterLocalOnlyHotspotCallbackTriggered() throws Exception {
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
- .thenReturn(ERROR_INCOMPATIBLE_MODE);
+ when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+ anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE);
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
mLooper.dispatchAll();
assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);