Merge "Use FrameworkStatsLog instead of StatsLog"
diff --git a/api/current.txt b/api/current.txt
index 32fb1e7..4533e37 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -47070,8 +47070,8 @@
}
public class MmsManager {
- method public void downloadMultimediaMessage(int, @NonNull String, @NonNull android.net.Uri, @Nullable android.os.Bundle, @Nullable android.app.PendingIntent);
- method public void sendMultimediaMessage(int, @NonNull android.net.Uri, @Nullable String, @Nullable android.os.Bundle, @Nullable android.app.PendingIntent);
+ method public void downloadMultimediaMessage(int, @NonNull String, @NonNull android.net.Uri, @Nullable android.os.Bundle, @Nullable android.app.PendingIntent, long);
+ method public void sendMultimediaMessage(int, @NonNull android.net.Uri, @Nullable String, @Nullable android.os.Bundle, @Nullable android.app.PendingIntent, long);
}
@Deprecated public class NeighboringCellInfo implements android.os.Parcelable {
diff --git a/api/system-current.txt b/api/system-current.txt
index 0596b3d..03229c7 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4484,11 +4484,11 @@
}
public static interface MediaSessionManager.OnMediaKeyEventDispatchedListener {
- method public default void onMediaKeyEventDispatched(@NonNull android.view.KeyEvent, @NonNull String, @Nullable android.media.session.MediaSession.Token);
+ method public void onMediaKeyEventDispatched(@NonNull android.view.KeyEvent, @NonNull String, @Nullable android.media.session.MediaSession.Token);
}
public static interface MediaSessionManager.OnMediaKeyEventSessionChangedListener {
- method public default void onMediaKeyEventSessionChanged(@NonNull String, @Nullable android.media.session.MediaSession.Token);
+ method public void onMediaKeyEventSessionChanged(@NonNull String, @Nullable android.media.session.MediaSession.Token);
}
public static interface MediaSessionManager.OnMediaKeyListener {
@@ -7622,7 +7622,6 @@
method public boolean isApMacRandomizationSupported();
method public boolean isConnectedMacRandomizationSupported();
method @Deprecated public boolean isDeviceToDeviceRttSupported();
- method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public boolean isDualModeSupported();
method public boolean isPortableHotspotSupported();
method public boolean isVerboseLoggingEnabled();
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isWifiApEnabled();
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 4b336ee..0906b35 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -180,7 +180,7 @@
PhoneServiceStateChanged phone_service_state_changed = 94 [(module) = "framework"];
PhoneStateChanged phone_state_changed = 95 [(module) = "framework"];
UserRestrictionChanged user_restriction_changed = 96;
- SettingsUIChanged settings_ui_changed = 97;
+ SettingsUIChanged settings_ui_changed = 97 [(module) = "settings"];
ConnectivityStateChanged connectivity_state_changed = 98 [(module) = "framework"];
// TODO: service state change is very noisy shortly after boot, as well
// as at other transitions - coming out of doze, device plugged in, etc.
diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h
index 0f33c56..463a1b6 100644
--- a/cmds/statsd/src/logd/LogEvent.h
+++ b/cmds/statsd/src/logd/LogEvent.h
@@ -255,7 +255,15 @@
mValid = false;
value = 0; // all primitive types can successfully cast 0
} else {
- value = *((T*)mBuf);
+ // When alignof(T) == 1, hopefully the compiler can optimize away
+ // this conditional as always true.
+ if ((reinterpret_cast<uintptr_t>(mBuf) % alignof(T)) == 0) {
+ // We're properly aligned, and can safely make this assignment.
+ value = *((T*)mBuf);
+ } else {
+ // We need to use memcpy. It's slower, but safe.
+ memcpy(&value, mBuf, sizeof(T));
+ }
mBuf += sizeof(T);
mRemainingLen -= sizeof(T);
}
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index d8b5e7f..f31c614 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -2873,7 +2873,13 @@
}
/**
- * Called by the system when picture in picture mode should be entered if supported.
+ * This method is called by the system in various cases where picture in picture mode should be
+ * entered if supported.
+ *
+ * <p>It is up to the app developer to choose whether to call
+ * {@link #enterPictureInPictureMode(PictureInPictureParams)} at this time. For example, the
+ * system will call this method when the activity is being put into the background, so the app
+ * developer might want to switch an activity into PIP mode instead.</p>
*/
public void onPictureInPictureRequested() {
// Previous recommendation was for apps to enter picture-in-picture in onUserLeaveHint()
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 9666c12..605c585 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8711,6 +8711,14 @@
"back_gesture_inset_scale_right";
/**
+ * Current provider of proximity-based sharing services.
+ * Default value in @string/config_defaultNearbySharingComponent.
+ * No VALIDATOR as this setting will not be backed up.
+ * @hide
+ */
+ public static final String NEARBY_SHARING_COMPONENT = "nearby_sharing_component";
+
+ /**
* Controls whether aware is enabled.
* @hide
*/
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index c8a7c07..78d4e61 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -28,6 +28,7 @@
import android.app.ITransientNotificationCallback;
import android.compat.Compatibility;
import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledAfter;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.Configuration;
@@ -112,11 +113,9 @@
/**
* Text toasts will be rendered by SystemUI instead of in-app, so apps can't circumvent
* background custom toast restrictions.
- *
- * TODO(b/144152069): Add @EnabledAfter(Q) to target R+ after assessing impact on dogfood
*/
@ChangeId
- // @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
+ @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
private static final long CHANGE_TEXT_TOASTS_IN_THE_SYSTEM = 147798919L;
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 65128e4..a284248 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -53,6 +53,7 @@
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.database.Cursor;
import android.database.DataSetObserver;
import android.graphics.Bitmap;
@@ -81,6 +82,7 @@
import android.provider.DocumentsContract;
import android.provider.Downloads;
import android.provider.OpenableColumns;
+import android.provider.Settings;
import android.service.chooser.ChooserTarget;
import android.service.chooser.ChooserTargetService;
import android.service.chooser.IChooserTargetResult;
@@ -101,6 +103,7 @@
import android.view.ViewGroup.LayoutParams;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
+import android.widget.Button;
import android.widget.ImageView;
import android.widget.Space;
import android.widget.TextView;
@@ -131,6 +134,7 @@
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.net.URISyntaxException;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
@@ -166,6 +170,9 @@
private static final String PREF_NUM_SHEET_EXPANSIONS = "pref_num_sheet_expansions";
+ private static final String CHIP_LABEL_METADATA_KEY = "android.service.chooser.chip_label";
+ private static final String CHIP_ICON_METADATA_KEY = "android.service.chooser.chip_icon";
+
private static final boolean DEBUG = true;
private static final boolean USE_PREDICTION_MANAGER_FOR_SHARE_ACTIVITIES = true;
@@ -527,6 +534,15 @@
mIsSuccessfullySelected = false;
Intent intent = getIntent();
Parcelable targetParcelable = intent.getParcelableExtra(Intent.EXTRA_INTENT);
+ if (targetParcelable instanceof Uri) {
+ try {
+ targetParcelable = Intent.parseUri(targetParcelable.toString(),
+ Intent.URI_INTENT_SCHEME);
+ } catch (URISyntaxException ex) {
+ // doesn't parse as an intent; let the next test fail and error out
+ }
+ }
+
if (!(targetParcelable instanceof Intent)) {
Log.w("ChooserActivity", "Target is not an intent: " + targetParcelable);
finish();
@@ -965,6 +981,108 @@
return displayContentPreview(previewType, targetIntent, getLayoutInflater(), parent);
}
+ private ComponentName getNearbySharingComponent() {
+ String nearbyComponent = Settings.Secure.getString(
+ getContentResolver(),
+ Settings.Secure.NEARBY_SHARING_COMPONENT);
+ if (TextUtils.isEmpty(nearbyComponent)) {
+ nearbyComponent = getString(R.string.config_defaultNearbySharingComponent);
+ }
+ if (TextUtils.isEmpty(nearbyComponent)) {
+ return null;
+ }
+ return ComponentName.unflattenFromString(nearbyComponent);
+ }
+
+ private TargetInfo getNearbySharingTarget(Intent originalIntent) {
+ final ComponentName cn = getNearbySharingComponent();
+ if (cn == null) return null;
+
+ final Intent resolveIntent = new Intent();
+ resolveIntent.setComponent(cn);
+ final ResolveInfo ri = getPackageManager().resolveActivity(
+ resolveIntent, PackageManager.GET_META_DATA);
+ if (ri == null || ri.activityInfo == null) {
+ Log.e(TAG, "Device-specified nearby sharing component (" + cn
+ + ") not available");
+ return null;
+ }
+
+ // Allow the nearby sharing component to provide a more appropriate icon and label
+ // for the chip.
+ CharSequence name = null;
+ Drawable icon = null;
+ final Bundle metaData = ri.activityInfo.metaData;
+ if (metaData != null) {
+ try {
+ final Resources pkgRes = getPackageManager().getResourcesForActivity(cn);
+ final int nameResId = metaData.getInt(CHIP_LABEL_METADATA_KEY);
+ name = pkgRes.getString(nameResId);
+ final int resId = metaData.getInt(CHIP_ICON_METADATA_KEY);
+ icon = pkgRes.getDrawable(resId);
+ } catch (Resources.NotFoundException ex) {
+ } catch (NameNotFoundException ex) {
+ }
+ }
+ if (TextUtils.isEmpty(name)) {
+ name = ri.loadLabel(getPackageManager());
+ }
+ if (icon == null) {
+ icon = ri.loadIcon(getPackageManager());
+ }
+
+ final DisplayResolveInfo dri = new DisplayResolveInfo(
+ originalIntent, ri, name, "", resolveIntent, null);
+ dri.setDisplayIcon(icon);
+ return dri;
+ }
+
+ private Button createActionButton(Drawable icon, CharSequence title, View.OnClickListener r) {
+ Button b = (Button) LayoutInflater.from(this).inflate(R.layout.chooser_action_button, null);
+ if (icon != null) {
+ final int size = getResources()
+ .getDimensionPixelSize(R.dimen.chooser_action_button_icon_size);
+ icon.setBounds(0, 0, size, size);
+ b.setCompoundDrawablesRelative(icon, null, null, null);
+ }
+ b.setText(title);
+ b.setOnClickListener(r);
+ return b;
+ }
+
+ private Button createCopyButton() {
+ final Button b = createActionButton(
+ getDrawable(R.drawable.ic_menu_copy_material),
+ getString(R.string.copy), this::onCopyButtonClicked);
+ b.setId(R.id.chooser_copy_button);
+ return b;
+ }
+
+ private @Nullable Button createNearbyButton(Intent originalIntent) {
+ final TargetInfo ti = getNearbySharingTarget(originalIntent);
+ if (ti == null) return null;
+
+ return createActionButton(
+ ti.getDisplayIcon(this),
+ ti.getDisplayLabel(),
+ (View unused) -> {
+ safelyStartActivity(ti);
+ finish();
+ }
+ );
+ }
+
+ private void addActionButton(ViewGroup parent, Button b) {
+ if (b == null) return;
+ final ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams(
+ LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT
+ );
+ final int gap = getResources().getDimensionPixelSize(R.dimen.resolver_icon_margin) / 2;
+ lp.setMarginsRelative(gap, 0, gap, 0);
+ parent.addView(b, lp);
+ }
+
private ViewGroup displayContentPreview(@ContentPreviewType int previewType,
Intent targetIntent, LayoutInflater layoutInflater, ViewGroup parent) {
ViewGroup layout = null;
@@ -995,8 +1113,10 @@
ViewGroup contentPreviewLayout = (ViewGroup) layoutInflater.inflate(
R.layout.chooser_grid_preview_text, parent, false);
- contentPreviewLayout.findViewById(R.id.copy_button).setOnClickListener(
- this::onCopyButtonClicked);
+ final ViewGroup actionRow =
+ (ViewGroup) contentPreviewLayout.findViewById(R.id.chooser_action_row);
+ addActionButton(actionRow, createCopyButton());
+ addActionButton(actionRow, createNearbyButton(targetIntent));
CharSequence sharingText = targetIntent.getCharSequenceExtra(Intent.EXTRA_TEXT);
if (sharingText == null) {
@@ -1154,7 +1274,8 @@
// TODO(b/120417119): Disable file copy until after moving to sysui,
// due to permissions issues
- contentPreviewLayout.findViewById(R.id.file_copy_button).setVisibility(View.GONE);
+ //((ViewGroup) contentPreviewLayout.findViewById(R.id.chooser_action_row))
+ // .addView(createCopyButton());
String action = targetIntent.getAction();
if (Intent.ACTION_SEND.equals(action)) {
@@ -1680,7 +1801,7 @@
}
return intentFilter;
} catch (Exception e) {
- Log.e(TAG, "failed to get target intent filter " + e);
+ Log.e(TAG, "failed to get target intent filter", e);
return null;
}
}
diff --git a/core/java/com/android/internal/app/NetInitiatedActivity.java b/core/java/com/android/internal/app/NetInitiatedActivity.java
index 89aa770..92e9fe4 100644
--- a/core/java/com/android/internal/app/NetInitiatedActivity.java
+++ b/core/java/com/android/internal/app/NetInitiatedActivity.java
@@ -23,7 +23,7 @@
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
-import android.location.LocationManager;
+import android.location.LocationManagerInternal;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
@@ -32,6 +32,7 @@
import com.android.internal.R;
import com.android.internal.location.GpsNetInitiatedHandler;
+import com.android.server.LocalServices;
/**
* This activity is shown to the user for him/her to accept or deny network-initiated
@@ -68,14 +69,14 @@
private final Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
- case GPS_NO_RESPONSE_TIME_OUT: {
- if (notificationId != -1) {
- sendUserResponse(default_response);
+ case GPS_NO_RESPONSE_TIME_OUT: {
+ if (notificationId != -1) {
+ sendUserResponse(default_response);
+ }
+ finish();
}
- finish();
- }
- break;
- default:
+ break;
+ default:
}
}
};
@@ -137,9 +138,8 @@
// Respond to NI Handler under GnssLocationProvider, 1 = accept, 2 = deny
private void sendUserResponse(int response) {
if (DEBUG) Log.d(TAG, "sendUserResponse, response: " + response);
- LocationManager locationManager = (LocationManager)
- this.getSystemService(Context.LOCATION_SERVICE);
- locationManager.sendNiResponse(notificationId, response);
+ LocationManagerInternal lm = LocalServices.getService(LocationManagerInternal.class);
+ lm.sendNiResponse(notificationId, response);
}
@UnsupportedAppUsage
diff --git a/core/java/com/android/internal/compat/ChangeReporter.java b/core/java/com/android/internal/compat/ChangeReporter.java
index e0eb9af..c50ff35 100644
--- a/core/java/com/android/internal/compat/ChangeReporter.java
+++ b/core/java/com/android/internal/compat/ChangeReporter.java
@@ -18,10 +18,10 @@
import android.util.Log;
import android.util.Slog;
-import android.util.StatsLog;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.FrameworkStatsLog;
import java.util.HashMap;
import java.util.HashSet;
@@ -85,8 +85,8 @@
*/
public void reportChange(int uid, long changeId, int state) {
if (shouldWriteToStatsLog(uid, changeId, state)) {
- StatsLog.write(StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED, uid, changeId,
- state, mSource);
+ FrameworkStatsLog.write(FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED, uid,
+ changeId, state, mSource);
}
if (shouldWriteToDebug(uid, changeId, state)) {
debugLog(uid, changeId, state);
@@ -174,7 +174,7 @@
private void debugLog(int uid, long changeId, int state) {
String message = String.format("Compat change id reported: %d; UID %d; state: %s", changeId,
uid, stateToString(state));
- if (mSource == StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__SOURCE__SYSTEM_SERVER) {
+ if (mSource == FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__SOURCE__SYSTEM_SERVER) {
Slog.d(TAG, message);
} else {
Log.d(TAG, message);
@@ -183,18 +183,18 @@
}
/**
- * Transforms StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE enum to a string.
+ * Transforms FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE enum to a string.
*
* @param state to transform
* @return a string representing the state
*/
private static String stateToString(int state) {
switch (state) {
- case StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED:
+ case FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED:
return "LOGGED";
- case StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__ENABLED:
+ case FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__ENABLED:
return "ENABLED";
- case StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__DISABLED:
+ case FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__DISABLED:
return "DISABLED";
default:
return "UNKNOWN";
diff --git a/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
index 4de6c86..39483b5 100644
--- a/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
+++ b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
@@ -277,13 +277,6 @@
SkWStream* CreateJavaOutputStreamAdaptor(JNIEnv* env, jobject stream,
jbyteArray storage) {
- static bool gInited;
-
- if (!gInited) {
-
- gInited = true;
- }
-
return new SkJavaOutputStream(env, stream, storage);
}
diff --git a/core/res/res/drawable/chooser_action_button_bg.xml b/core/res/res/drawable/chooser_action_button_bg.xml
new file mode 100644
index 0000000..a434c0b
--- /dev/null
+++ b/core/res/res/drawable/chooser_action_button_bg.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 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
+ -->
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ android:color="@color/lighter_gray">
+ <item>
+ <inset
+ android:insetLeft="0dp"
+ android:insetTop="8dp"
+ android:insetRight="0dp"
+ android:insetBottom="8dp">
+ <shape android:shape="rectangle">
+ <corners android:radius="16dp"></corners>
+ <stroke android:width="1dp"
+ android:color="?attr/textColorSecondary" />
+ <solid android:color="?attr/colorBackground" />
+ </shape>
+ </inset>
+ </item>
+</ripple>
diff --git a/core/res/res/drawable/ic_content_copy_gm2.xml b/core/res/res/drawable/ic_content_copy_gm2.xml
deleted file mode 100644
index ee58738..0000000
--- a/core/res/res/drawable/ic_content_copy_gm2.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24"
- android:viewportHeight="24">
- <path
- android:fillColor="?android:attr/textColorSecondary"
- android:pathData="M18,21L4,21L4,7L2,7v14c0,1.1 0.9,2 2,2h14v-2zM21,17L21,3c0,-1.1 -0.9,-2 -2,-2L8,1c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h11c1.1,0 2,-0.9 2,-2zM19,17L8,17L8,3h11v14z"/>
-</vector>
diff --git a/core/res/res/drawable/ic_menu_copy_material.xml b/core/res/res/drawable/ic_menu_copy_material.xml
index c03723b..8c9f1c5 100644
--- a/core/res/res/drawable/ic_menu_copy_material.xml
+++ b/core/res/res/drawable/ic_menu_copy_material.xml
@@ -1,26 +1,27 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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
+ 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
+ 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.
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
-->
+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0"
- android:autoMirrored="true"
- android:tint="?attr/colorControlNormal">
- <path
- android:pathData="M16,1L4,1C2.9,1 2,1.9 2,3l0,14l2,0L4,3l12,0L16,1zM19,5L8,5C6.9,5 6,5.9 6,7l0,14c0,1.1 0.9,2 2,2l11,0c1.1,0 2,-0.9 2,-2L21,7C21,5.9 20.1,5 19,5zM19,21L8,21L8,7l11,0L19,21z"
- android:fillColor="@color/white"/>
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:autoMirrored="true"
+ android:tint="?attr/colorControlNormal">
+ <path
+ android:fillColor="@color/white"
+ android:pathData="M18,21L4,21L4,7L2,7v14c0,1.1 0.9,2 2,2h14v-2zM21,17L21,3c0,-1.1 -0.9,-2 -2,-2L8,1c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h11c1.1,0 2,-0.9 2,-2zM19,17L8,17L8,3h11v14z"/>
</vector>
diff --git a/core/res/res/layout/chooser_action_button.xml b/core/res/res/layout/chooser_action_button.xml
new file mode 100644
index 0000000..119b2e9
--- /dev/null
+++ b/core/res/res/layout/chooser_action_button.xml
@@ -0,0 +1,30 @@
+<!--
+ ~ Copyright (C) 2019 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
+ -->
+
+<Button xmlns:android="http://schemas.android.com/apk/res/android"
+ android:gravity="center_vertical|start"
+ android:paddingStart="12dp"
+ android:paddingEnd="12dp"
+ android:drawablePadding="8dp"
+ android:textColor="?android:textColorSecondary"
+ android:textSize="12sp"
+ android:maxWidth="192dp"
+ android:singleLine="true"
+ android:clickable="true"
+ android:background="@drawable/chooser_action_button_bg"
+ android:drawableTint="?android:attr/colorControlNormal"
+ android:drawableTintMode="src_in"
+ />
diff --git a/core/res/res/layout/chooser_action_row.xml b/core/res/res/layout/chooser_action_row.xml
new file mode 100644
index 0000000..ea75611
--- /dev/null
+++ b/core/res/res/layout/chooser_action_row.xml
@@ -0,0 +1,26 @@
+<!--
+ ~ Copyright (C) 2019 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
+ -->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="@dimen/chooser_edge_margin_normal"
+ android:paddingRight="@dimen/chooser_edge_margin_normal"
+ android:gravity="center"
+ >
+
+</LinearLayout>
diff --git a/core/res/res/layout/chooser_grid_preview_file.xml b/core/res/res/layout/chooser_grid_preview_file.xml
index f7d60c9..2a39215 100644
--- a/core/res/res/layout/chooser_grid_preview_file.xml
+++ b/core/res/res/layout/chooser_grid_preview_file.xml
@@ -65,13 +65,15 @@
android:gravity="start|top"
android:paddingRight="24dp"
android:singleLine="true"/>
- <Button
- android:id="@+id/file_copy_button"
- android:layout_width="24dp"
- android:layout_height="24dp"
- android:gravity="center"
- android:layout_gravity="center_vertical"
- android:background="@drawable/ic_content_copy_gm2"/>
</LinearLayout>
+
+ <include
+ android:id="@+id/chooser_action_row"
+ layout="@layout/chooser_action_row"
+ android:layout_width="@dimen/chooser_preview_width"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/chooser_view_spacing"
+ android:layout_gravity="center"
+ />
</LinearLayout>
diff --git a/core/res/res/layout/chooser_grid_preview_image.xml b/core/res/res/layout/chooser_grid_preview_image.xml
index 79a0de4..62df165 100644
--- a/core/res/res/layout/chooser_grid_preview_image.xml
+++ b/core/res/res/layout/chooser_grid_preview_image.xml
@@ -78,5 +78,15 @@
android:scaleType="centerCrop"/>
</RelativeLayout>
+
+ <include
+ android:id="@+id/chooser_action_row"
+ layout="@layout/chooser_action_row"
+ android:layout_width="@dimen/chooser_preview_width"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/chooser_view_spacing"
+ android:layout_gravity="center"
+ />
+
</LinearLayout>
diff --git a/core/res/res/layout/chooser_grid_preview_text.xml b/core/res/res/layout/chooser_grid_preview_text.xml
index 4d7846d..0029174 100644
--- a/core/res/res/layout/chooser_grid_preview_text.xml
+++ b/core/res/res/layout/chooser_grid_preview_text.xml
@@ -37,10 +37,9 @@
<TextView
android:id="@+id/content_preview_text"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
- android:layout_toStartOf="@id/copy_button"
android:layout_centerVertical="true"
android:ellipsize="end"
android:fontFamily="@android:string/config_headlineFontFamily"
@@ -48,40 +47,17 @@
android:maxLines="2"
android:focusable="true"/>
- <LinearLayout
- android:id="@+id/copy_button"
- android:orientation="vertical"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:layout_alignParentEnd="true"
- android:layout_marginStart="@dimen/chooser_view_spacing"
- android:gravity="center"
- android:minWidth="48dp"
- android:minHeight="48dp"
- android:clickable="true"
- style="?attr/borderlessButtonStyle">
-
- <ImageView
- android:layout_width="24dp"
- android:layout_height="24dp"
- android:gravity="top|center_horizontal"
- android:src="@drawable/ic_content_copy_gm2" />
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="4dp"
- android:gravity="center_horizontal"
- android:text="@string/copy"
- android:textColor="?android:textColorSecondary"
- android:textSize="12sp"
- android:maxWidth="72dp"
- android:maxLines="2"
- android:ellipsize="end" />
- </LinearLayout>
</RelativeLayout>
+ <include
+ android:id="@+id/chooser_action_row"
+ layout="@layout/chooser_action_row"
+ android:layout_width="@dimen/chooser_preview_width"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/chooser_view_spacing"
+ android:layout_gravity="center"
+ />
+
<!-- Required sub-layout so we can get the nice rounded corners-->
<!-- around this section -->
<LinearLayout
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index e98f8ba..52b92d2 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4323,4 +4323,12 @@
<item>4</item> <!-- PROCESS_STATE_FOREGROUND_SERVICE -->
<item>12</item> <!-- PROCESS_STATE_TOP_SLEEPING -->
</integer-array>
+
+ <!-- Component name that accepts ACTION_SEND intents for nearby (proximity-based) sharing.
+ Used by ChooserActivity. -->
+ <string translatable="false" name="config_defaultNearbySharingComponent"></string>
+
+ <!-- Boolean indicating whether frameworks needs to reset cell broadcast geo-fencing
+ check after reboot or airplane mode toggling -->
+ <bool translatable="false" name="reset_geo_fencing_check_after_boot_or_apm">false</bool>
</resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index d437aa1..0b5082c 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -774,6 +774,8 @@
<dimen name="resolver_edge_margin">24dp</dimen>
<dimen name="resolver_elevation">1dp</dimen>
+ <dimen name="chooser_action_button_icon_size">18dp</dimen>
+
<!-- Assistant handles -->
<dimen name="assist_handle_shadow_radius">2dp</dimen>
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index ddd9ba4..51ed08b 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -194,6 +194,9 @@
<!-- A tag used to save the index where the custom view is stored -->
<item type="id" name="notification_custom_view_index_tag" />
+ <!-- Marks the "copy to clipboard" button in the ChooserActivity -->
+ <item type="id" name="chooser_copy_button" />
+
<!-- Accessibility action identifier for {@link android.accessibilityservice.AccessibilityService#GLOBAL_ACTION_BACK}. -->
<item type="id" name="accessibilitySystemActionBack" />
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index e4717f8..21128e3 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -66,8 +66,7 @@
<java-symbol type="id" name="content_preview_text_layout" />
<java-symbol type="id" name="content_preview_title" />
<java-symbol type="id" name="content_preview_title_layout" />
- <java-symbol type="id" name="copy_button" />
- <java-symbol type="id" name="file_copy_button" />
+ <java-symbol type="id" name="chooser_action_row" />
<java-symbol type="id" name="current_scene" />
<java-symbol type="id" name="scene_layoutid_cache" />
<java-symbol type="id" name="customPanel" />
@@ -3783,6 +3782,11 @@
<java-symbol type="string" name="config_factoryResetPackage" />
<java-symbol type="array" name="config_highRefreshRateBlacklist" />
+ <java-symbol type="id" name="chooser_copy_button" />
+ <java-symbol type="layout" name="chooser_action_button" />
+ <java-symbol type="dimen" name="chooser_action_button_icon_size" />
+ <java-symbol type="string" name="config_defaultNearbySharingComponent" />
+
<java-symbol type="bool" name="config_automotiveHideNavBarForKeyboard" />
<java-symbol type="bool" name="config_showBuiltinWirelessChargingAnim" />
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
index d4c3621..df6b906 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -64,7 +64,6 @@
import android.graphics.drawable.Icon;
import android.metrics.LogMaker;
import android.net.Uri;
-import android.os.Bundle;
import android.os.UserHandle;
import android.service.chooser.ChooserTarget;
@@ -77,9 +76,6 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
-import org.hamcrest.Matcher;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
@@ -482,8 +478,8 @@
.launchActivity(Intent.createChooser(sendIntent, null));
waitForIdle();
- onView(withId(R.id.copy_button)).check(matches(isDisplayed()));
- onView(withId(R.id.copy_button)).perform(click());
+ onView(withId(R.id.chooser_copy_button)).check(matches(isDisplayed()));
+ onView(withId(R.id.chooser_copy_button)).perform(click());
ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(
Context.CLIPBOARD_SERVICE);
ClipData clipData = clipboard.getPrimaryClip();
@@ -510,8 +506,8 @@
.launchActivity(Intent.createChooser(sendIntent, null));
waitForIdle();
- onView(withId(R.id.copy_button)).check(matches(isDisplayed()));
- onView(withId(R.id.copy_button)).perform(click());
+ onView(withId(R.id.chooser_copy_button)).check(matches(isDisplayed()));
+ onView(withId(R.id.chooser_copy_button)).perform(click());
verify(mockLogger, atLeastOnce()).write(logMakerCaptor.capture());
// First is Activity shown, Second is "with preview"
diff --git a/data/etc/hiddenapi-package-whitelist.xml b/data/etc/hiddenapi-package-whitelist.xml
index 3997371..5c89da0 100644
--- a/data/etc/hiddenapi-package-whitelist.xml
+++ b/data/etc/hiddenapi-package-whitelist.xml
@@ -53,10 +53,6 @@
<hidden-api-whitelisted-app package="com.android.providers.media" />
<hidden-api-whitelisted-app package="com.android.providers.tv" />
<hidden-api-whitelisted-app package="com.android.providers.userdictionary" />
- <!-- TODO (b/141954427): Remove networkstack -->
- <hidden-api-whitelisted-app package="com.android.networkstack" />
- <!-- TODO (b/141954427): Remove wifistack -->
- <hidden-api-whitelisted-app package="com.android.wifi" />
<hidden-api-whitelisted-app package="com.android.smspush" />
<hidden-api-whitelisted-app package="com.android.spare_parts" />
<hidden-api-whitelisted-app package="com.android.statementservice" />
diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl
index 79bec92..6a5c0ec 100644
--- a/location/java/android/location/ILocationManager.aidl
+++ b/location/java/android/location/ILocationManager.aidl
@@ -69,8 +69,6 @@
double upperRightLatitude, double upperRightLongitude, int maxResults,
in GeocoderParams params, out List<Address> addrs);
- boolean sendNiResponse(int notifId, int userResponse);
-
boolean addGnssMeasurementsListener(in IGnssMeasurementsListener listener,
String packageName, String featureId, String listenerIdentifier);
void injectGnssMeasurementCorrections(in GnssMeasurementCorrections corrections,
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 0c5fe78..197787e 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -2397,21 +2397,6 @@
}
}
- /**
- * Used by NetInitiatedActivity to report user response
- * for network initiated GPS fix requests.
- *
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- public boolean sendNiResponse(int notifId, int userResponse) {
- try {
- return mService.sendNiResponse(notifId, userResponse);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
private void checkPendingIntent(PendingIntent pendingIntent) {
Preconditions.checkArgument(pendingIntent != null, "invalid null pending intent");
if (!pendingIntent.isTargetedToPackage()) {
diff --git a/location/java/android/location/LocationManagerInternal.java b/location/java/android/location/LocationManagerInternal.java
index 44d9d23..69162ba 100644
--- a/location/java/android/location/LocationManagerInternal.java
+++ b/location/java/android/location/LocationManagerInternal.java
@@ -41,4 +41,19 @@
* @throws IllegalArgumentException if provider is null
*/
public abstract void requestSetProviderAllowed(@NonNull String provider, boolean allowed);
+
+ /**
+ * Returns true if the given package belongs to a location provider, and so should be afforded
+ * some special privileges.
+ *
+ * @param packageName The package name to check
+ * @return True is the given package belongs to a location provider, false otherwise
+ */
+ public abstract boolean isProviderPackage(@NonNull String packageName);
+
+ /**
+ * Should only be used by GNSS code.
+ */
+ // TODO: there is no reason for this to exist as part of any API. move all the logic into gnss
+ public abstract void sendNiResponse(int notifId, int userResponse);
}
diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
index aece39d..5ef466d 100644
--- a/media/java/android/media/session/MediaSessionManager.java
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -932,7 +932,7 @@
}
/**
- * Listener to receive when the media session service
+ * Listener to be called when the media session service dispatches a media key event.
* @hide
*/
@SystemApi
@@ -944,15 +944,15 @@
* is released.
*
* @param event Dispatched media key event.
- * @param packageName Package
+ * @param packageName The package name
* @param sessionToken The media session's token. Can be {@code null}.
*/
- default void onMediaKeyEventDispatched(@NonNull KeyEvent event, @NonNull String packageName,
- @Nullable MediaSession.Token sessionToken) { }
+ void onMediaKeyEventDispatched(@NonNull KeyEvent event, @NonNull String packageName,
+ @Nullable MediaSession.Token sessionToken);
}
/**
- * Listener to receive changes in the media key event session, which would receive the media key
+ * Listener to receive changes in the media key event session, which would receive a media key
* event unless specified.
* @hide
*/
@@ -964,13 +964,14 @@
* has specified the target.
* <p>
* The session token can be {@link null} if the media button session is unset. In that case,
- * framework would dispatch to the last sessions's media button receiver.
+ * framework would dispatch to the last sessions's media button receiver. If the media
+ * button receive isn't set as well, then it
*
* @param packageName The package name who would receive the media key event. Can be empty.
- * @param sessionToken The media session's token. Can be {@code null.}
+ * @param sessionToken The media session's token. Can be {@code null}.
*/
- default void onMediaKeyEventSessionChanged(@NonNull String packageName,
- @Nullable MediaSession.Token sessionToken) { }
+ void onMediaKeyEventSessionChanged(@NonNull String packageName,
+ @Nullable MediaSession.Token sessionToken);
}
/**
diff --git a/mms/java/android/telephony/MmsManager.java b/mms/java/android/telephony/MmsManager.java
index cf55eba..f07cd5e 100644
--- a/mms/java/android/telephony/MmsManager.java
+++ b/mms/java/android/telephony/MmsManager.java
@@ -55,10 +55,12 @@
* sending the message.
* @param sentIntent if not NULL this <code>PendingIntent</code> is broadcast when the message
* is successfully sent, or failed
+ * @param messageId an id that uniquely identifies the message requested to be sent.
+ * Used for logging and diagnostics purposes. The id may be 0.
*/
public void sendMultimediaMessage(int subId, @NonNull Uri contentUri,
@Nullable String locationUrl, @Nullable Bundle configOverrides,
- @Nullable PendingIntent sentIntent) {
+ @Nullable PendingIntent sentIntent, long messageId) {
try {
final IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms"));
if (iMms == null) {
@@ -66,7 +68,7 @@
}
iMms.sendMessage(subId, ActivityThread.currentPackageName(), contentUri,
- locationUrl, configOverrides, sentIntent);
+ locationUrl, configOverrides, sentIntent, messageId);
} catch (RemoteException e) {
// Ignore it
}
@@ -83,18 +85,22 @@
* downloading the message.
* @param downloadedIntent if not NULL this <code>PendingIntent</code> is
* broadcast when the message is downloaded, or the download is failed
+ * @param messageId an id that uniquely identifies the message requested to be downloaded.
+ * Used for logging and diagnostics purposes. The id may be 0.
+ * downloaded.
* @throws IllegalArgumentException if locationUrl or contentUri is empty
*/
public void downloadMultimediaMessage(int subId, @NonNull String locationUrl,
@NonNull Uri contentUri, @Nullable Bundle configOverrides,
- @Nullable PendingIntent downloadedIntent) {
+ @Nullable PendingIntent downloadedIntent, long messageId) {
try {
final IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms"));
if (iMms == null) {
return;
}
iMms.downloadMessage(subId, ActivityThread.currentPackageName(),
- locationUrl, contentUri, configOverrides, downloadedIntent);
+ locationUrl, contentUri, configOverrides, downloadedIntent,
+ messageId);
} catch (RemoteException e) {
// Ignore it
}
diff --git a/mms/java/com/android/internal/telephony/IMms.aidl b/mms/java/com/android/internal/telephony/IMms.aidl
index 8be5111..e0e0a4a 100644
--- a/mms/java/com/android/internal/telephony/IMms.aidl
+++ b/mms/java/com/android/internal/telephony/IMms.aidl
@@ -37,9 +37,11 @@
* sending the message. See {@link android.telephony.SmsManager} for the value names and types.
* @param sentIntent if not NULL this <code>PendingIntent</code> is
* broadcast when the message is successfully sent, or failed
+ * @param messageId An id that uniquely identifies the message requested to be sent.
*/
void sendMessage(int subId, String callingPkg, in Uri contentUri,
- String locationUrl, in Bundle configOverrides, in PendingIntent sentIntent);
+ String locationUrl, in Bundle configOverrides, in PendingIntent sentIntent,
+ in long messageId);
/**
* Download an MMS message using known location and transaction id
@@ -54,10 +56,11 @@
* types.
* @param downloadedIntent if not NULL this <code>PendingIntent</code> is
* broadcast when the message is downloaded, or the download is failed
- */
+ * @param messageId An id that uniquely identifies the message requested to be downloaded.
+ */
void downloadMessage(int subId, String callingPkg, String locationUrl,
in Uri contentUri, in Bundle configOverrides,
- in PendingIntent downloadedIntent);
+ in PendingIntent downloadedIntent, in long messageId);
/**
* Import a text message into system's SMS store
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 65269c9..dee1d7e 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -728,6 +728,7 @@
Settings.Secure.DOZE_WAKE_DISPLAY_GESTURE,
Settings.Secure.FACE_UNLOCK_RE_ENROLL,
Settings.Secure.TAP_GESTURE,
+ Settings.Secure.NEARBY_SHARING_COMPONENT, // not user configurable
Settings.Secure.WINDOW_MAGNIFICATION,
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_MAGNIFICATION_CONTROLLER,
Settings.Secure.SUPPRESS_DOZE);
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
index c243309..581cf7a 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
@@ -86,6 +86,8 @@
private SurfaceView mMirrorSurfaceView;
private View mControlsView;
private View mOverlayView;
+ // The boundary of magnification frame.
+ private final Rect mMagnificationFrameBoundary = new Rect();
private MoveMirrorRunnable mMoveMirrorRunnable = new MoveMirrorRunnable();
@@ -93,7 +95,7 @@
mContext = context;
mHandler = handler;
Display display = mContext.getDisplay();
- display.getSize(mDisplaySize);
+ display.getRealSize(mDisplaySize);
mDisplayId = mContext.getDisplayId();
mWm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
@@ -114,6 +116,7 @@
return;
}
setInitialStartBounds();
+ setMagnificationFrameBoundary();
createOverlayWindow();
}
@@ -330,7 +333,7 @@
@Override
public void onClick(View v) {
setMoveOffset(v, mMoveFrameAmountShort);
- moveMirrorFromControls();
+ moveMirrorWindow(mMoveWindowOffset.x, mMoveWindowOffset.y);
}
@Override
@@ -370,10 +373,8 @@
case MotionEvent.ACTION_MOVE:
int xDiff = (int) (event.getRawX() - mLastDrag.x);
int yDiff = (int) (event.getRawY() - mLastDrag.y);
- mMagnificationFrame.offset(xDiff, yDiff);
+ moveMirrorWindow(xDiff, yDiff);
mLastDrag.set(event.getRawX(), event.getRawY());
- modifyWindowMagnification(mTransaction);
- mTransaction.apply();
return true;
}
return false;
@@ -393,11 +394,11 @@
}
}
- private void moveMirrorFromControls() {
- mMagnificationFrame.offset(mMoveWindowOffset.x, mMoveWindowOffset.y);
-
- modifyWindowMagnification(mTransaction);
- mTransaction.apply();
+ private void moveMirrorWindow(int xOffset, int yOffset) {
+ if (updateMagnificationFramePosition(xOffset, yOffset)) {
+ modifyWindowMagnification(mTransaction);
+ mTransaction.apply();
+ }
}
/**
@@ -414,6 +415,52 @@
return new Rect(left, top, right, bottom);
}
+ private void setMagnificationFrameBoundary() {
+ // Calculates width and height for magnification frame could exceed out the screen.
+ // TODO : re-calculating again when scale is changed.
+ // The half width of magnification frame.
+ final int halfWidth = mMagnificationFrame.width() / 2;
+ // The half height of magnification frame.
+ final int halfHeight = mMagnificationFrame.height() / 2;
+ // The scaled half width of magnified region.
+ final int scaledWidth = (int) (halfWidth / mScale);
+ // The scaled half height of magnified region.
+ final int scaledHeight = (int) (halfHeight / mScale);
+ final int exceededWidth = halfWidth - scaledWidth;
+ final int exceededHeight = halfHeight - scaledHeight;
+
+ mMagnificationFrameBoundary.set(-exceededWidth, -exceededHeight,
+ mDisplaySize.x + exceededWidth, mDisplaySize.y + exceededHeight);
+ }
+
+ /**
+ * Calculates and sets the real position of magnification frame based on the magnified region
+ * should be limited by the region of the display.
+ */
+ private boolean updateMagnificationFramePosition(int xOffset, int yOffset) {
+ mTmpRect.set(mMagnificationFrame);
+ mTmpRect.offset(xOffset, yOffset);
+
+ if (mTmpRect.left < mMagnificationFrameBoundary.left) {
+ mTmpRect.offsetTo(mMagnificationFrameBoundary.left, mTmpRect.top);
+ } else if (mTmpRect.right > mMagnificationFrameBoundary.right) {
+ final int leftOffset = mMagnificationFrameBoundary.right - mMagnificationFrame.width();
+ mTmpRect.offsetTo(leftOffset, mTmpRect.top);
+ }
+
+ if (mTmpRect.top < mMagnificationFrameBoundary.top) {
+ mTmpRect.offsetTo(mTmpRect.left, mMagnificationFrameBoundary.top);
+ } else if (mTmpRect.bottom > mMagnificationFrameBoundary.bottom) {
+ final int topOffset = mMagnificationFrameBoundary.bottom - mMagnificationFrame.height();
+ mTmpRect.offsetTo(mTmpRect.left, topOffset);
+ }
+
+ if (!mTmpRect.equals(mMagnificationFrame)) {
+ mMagnificationFrame.set(mTmpRect);
+ return true;
+ }
+ return false;
+ }
@Override
public void surfaceCreated(SurfaceHolder holder) {
createMirror();
@@ -431,7 +478,7 @@
@Override
public void run() {
if (mIsPressedDown) {
- moveMirrorFromControls();
+ moveMirrorWindow(mMoveWindowOffset.x, mMoveWindowOffset.y);
mHandler.postDelayed(mMoveMirrorRunnable, 100);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index ac06f95..e954163 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -866,10 +866,6 @@
mOverflowCallback.run();
}
- if (update.addedBubble != null) {
- mStackView.addBubble(update.addedBubble);
- }
-
// Collapsing? Do this first before remaining steps.
if (update.expandedChanged && !update.expanded) {
mStackView.setExpanded(false);
@@ -916,6 +912,10 @@
}
}
+ if (update.addedBubble != null) {
+ mStackView.addBubble(update.addedBubble);
+ }
+
if (update.updatedBubble != null) {
mStackView.updateBubble(update.updatedBubble);
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index 685bb94..6062a3d 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -526,8 +526,13 @@
R.layout.bubble_expanded_view, this /* root */, false /* attachToRoot */);
mOverflowExpandedView.setOverflow(true);
- mInflater.inflate(R.layout.bubble_overflow_button, this);
- mOverflowBtn = findViewById(R.id.bubble_overflow_button);
+ mOverflowBtn = (ImageView) mInflater.inflate(R.layout.bubble_overflow_button,
+ this /* root */,
+ false /* attachToRoot */);
+
+ mBubbleContainer.addView(mOverflowBtn, 0,
+ new FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
+
mOverflowBtn.setOnClickListener(v -> {
setSelectedBubble(null);
});
@@ -541,11 +546,13 @@
ColorDrawable bg = new ColorDrawable(bgColor);
AdaptiveIconDrawable adaptiveIcon = new AdaptiveIconDrawable(bg, fg);
mOverflowBtn.setImageDrawable(adaptiveIcon);
+
mOverflowBtn.setVisibility(GONE);
}
void showExpandedViewContents(int displayId) {
- if (mOverflowExpandedView.getVirtualDisplayId() == displayId) {
+ if (mOverflowExpandedView != null
+ && mOverflowExpandedView.getVirtualDisplayId() == displayId) {
mOverflowExpandedView.setContentVisibility(true);
} else if (mExpandedBubble != null
&& mExpandedBubble.getExpandedView().getVirtualDisplayId() == displayId) {
@@ -714,7 +721,7 @@
private void updateSystemGestureExcludeRects() {
// Exclude the region occupied by the first BubbleView in the stack
Rect excludeZone = mSystemGestureExclusionRects.get(0);
- if (mBubbleContainer.getChildCount() > 0) {
+ if (getBubbleCount() > 0) {
View firstBubble = mBubbleContainer.getChildAt(0);
excludeZone.set(firstBubble.getLeft(), firstBubble.getTop(), firstBubble.getRight(),
firstBubble.getBottom());
@@ -775,7 +782,7 @@
Log.d(TAG, "addBubble: " + bubble);
}
- if (mBubbleContainer.getChildCount() == 0) {
+ if (getBubbleCount() == 0) {
mStackOnLeftOrWillBe = mStackAnimationController.isStackOnLeftSide();
}
@@ -817,16 +824,13 @@
}
if (mIsExpanded) {
if (DEBUG_BUBBLE_STACK_VIEW) {
- Log.d(TAG, "Expanded && overflow > 0. Show overflow button at");
- Log.d(TAG, "x: " + mExpandedAnimationController.getOverflowBtnLeft());
- Log.d(TAG, "y: " + mExpandedAnimationController.getExpandedY());
+ Log.d(TAG, "Show overflow button.");
}
- mOverflowBtn.setX(mExpandedAnimationController.getOverflowBtnLeft());
- mOverflowBtn.setY(mExpandedAnimationController.getExpandedY());
mOverflowBtn.setVisibility(VISIBLE);
- mExpandedAnimationController.setShowOverflowBtn(true);
if (apply) {
- mExpandedAnimationController.expandFromStack(null /* after */);
+ mExpandedAnimationController.expandFromStack(() -> {
+ updatePointerPosition();
+ } /* after */);
}
} else {
if (DEBUG_BUBBLE_STACK_VIEW) {
@@ -947,7 +951,7 @@
if (mIsExpanded) {
if (isIntersecting(mBubbleContainer, x, y)) {
// Could be tapping or dragging a bubble while expanded
- for (int i = 0; i < mBubbleContainer.getChildCount(); i++) {
+ for (int i = 0; i < getBubbleCount(); i++) {
BadgedImageView view = (BadgedImageView) mBubbleContainer.getChildAt(i);
if (isIntersecting(view, x, y)) {
return view;
@@ -1103,7 +1107,7 @@
/** Return the BubbleView at the given index from the bubble container. */
public BadgedImageView getBubbleAt(int i) {
- return mBubbleContainer.getChildCount() > i
+ return getBubbleCount() > i
? (BadgedImageView) mBubbleContainer.getChildAt(i)
: null;
}
@@ -1567,7 +1571,7 @@
return;
}
if (!mIsExpanded) {
- if (mBubbleContainer.getChildCount() > 0) {
+ if (getBubbleCount() > 0) {
mBubbleContainer.getChildAt(0).getBoundsOnScreen(outRect);
}
// Increase the touch target size of the bubble
@@ -1661,7 +1665,7 @@
/** Sets the appropriate Z-order and dot position for each bubble in the stack. */
private void updateBubbleZOrdersAndDotPosition(boolean animate) {
- int bubbleCount = mBubbleContainer.getChildCount();
+ int bubbleCount = getBubbleCount();
for (int i = 0; i < bubbleCount; i++) {
BadgedImageView bv = (BadgedImageView) mBubbleContainer.getChildAt(i);
bv.setZ((mMaxBubbles * mBubbleElevation) - i);
@@ -1677,30 +1681,23 @@
if (expandedBubble == null) {
return;
}
-
int index = getBubbleIndex(expandedBubble);
- if (index >= mMaxBubbles) {
- // In between state, where extra bubble will be overflowed, and new bubble added
- index = 0;
- }
float bubbleLeftFromScreenLeft = mExpandedAnimationController.getBubbleLeft(index);
float halfBubble = mBubbleSize / 2f;
float bubbleCenter = bubbleLeftFromScreenLeft + halfBubble;
// Padding might be adjusted for insets, so get it directly from the view
bubbleCenter -= mExpandedViewContainer.getPaddingLeft();
-
- if (index >= mMaxBubbles) {
- Bubble first = mBubbleData.getBubbles().get(0);
- first.getExpandedView().setPointerPosition(bubbleCenter);
- } else {
- expandedBubble.getExpandedView().setPointerPosition(bubbleCenter);
- }
+ expandedBubble.getExpandedView().setPointerPosition(bubbleCenter);
}
/**
* @return the number of bubbles in the stack view.
*/
public int getBubbleCount() {
+ if (BubbleExperimentConfig.allowBubbleOverflow(mContext)) {
+ // Subtract 1 for the overflow button which is always in the bubble container.
+ return mBubbleContainer.getChildCount() - 1;
+ }
return mBubbleContainer.getChildCount();
}
@@ -1797,7 +1794,7 @@
/** For debugging only */
List<Bubble> getBubblesOnScreen() {
List<Bubble> bubbles = new ArrayList<>();
- for (int i = 0; i < mBubbleContainer.getChildCount(); i++) {
+ for (int i = 0; i < getBubbleCount(); i++) {
View child = mBubbleContainer.getChildAt(i);
if (child instanceof BadgedImageView) {
String key = ((BadgedImageView) child).getKey();
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
index 6d6969d..aa549dc 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
@@ -31,6 +31,7 @@
import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.bubbles.BubbleExperimentConfig;
import com.google.android.collect.Sets;
@@ -67,13 +68,13 @@
private float mBubblePaddingTop;
/** Size of each bubble. */
private float mBubbleSizePx;
- /** Width of the overflow button. */
- private float mOverflowBtnWidth;
+ /** Space between bubbles in row above expanded view. */
+ private float mSpaceBetweenBubbles;
/** Height of the status bar. */
private float mStatusBarHeight;
/** Size of display. */
private Point mDisplaySize;
- /** Max number of bubbles shown in row above expanded view.*/
+ /** Max number of bubbles shown in row above expanded view. */
private int mBubblesMaxRendered;
/** What the current screen orientation is. */
private int mScreenOrientation;
@@ -99,7 +100,6 @@
private boolean mSpringingBubbleToTouch = false;
private int mExpandedViewPadding;
- private boolean mShowOverflowBtn;
public ExpandedAnimationController(Point displaySize, int expandedViewPadding,
int orientation) {
@@ -153,14 +153,6 @@
}
}
- public void setShowOverflowBtn(boolean showBtn) {
- mShowOverflowBtn = showBtn;
- }
-
- public boolean getShowOverflowBtn() {
- return mShowOverflowBtn;
- }
-
/**
* Animates the bubbles along a curved path, either to expand them along the top or collapse
* them back into a stack.
@@ -369,10 +361,10 @@
}
final WindowInsets insets = mLayout.getRootWindowInsets();
return mBubblePaddingTop + Math.max(
- mStatusBarHeight,
- insets.getDisplayCutout() != null
- ? insets.getDisplayCutout().getSafeInsetTop()
- : 0);
+ mStatusBarHeight,
+ insets.getDisplayCutout() != null
+ ? insets.getDisplayCutout().getSafeInsetTop()
+ : 0);
}
/** Description of current animation controller state. */
@@ -391,11 +383,15 @@
mStackOffsetPx = res.getDimensionPixelSize(R.dimen.bubble_stack_offset);
mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top);
mBubbleSizePx = res.getDimensionPixelSize(R.dimen.individual_bubble_size);
- mOverflowBtnWidth = mBubbleSizePx;
mStatusBarHeight =
res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
mBubblesMaxRendered = res.getInteger(R.integer.bubbles_max_rendered);
+ // Includes overflow button.
+ float totalGapWidth = getWidthForDisplayingBubbles() - (mExpandedViewPadding * 2)
+ - (mBubblesMaxRendered + 1) * mBubbleSizePx;
+ mSpaceBetweenBubbles = totalGapWidth / mBubblesMaxRendered;
+
// Ensure that all child views are at 1x scale, and visible, in case they were animating
// in.
mLayout.setVisibility(View.VISIBLE);
@@ -506,18 +502,10 @@
* @return Bubble left x from left edge of screen.
*/
public float getBubbleLeft(int index) {
- final float bubbleFromRowLeft = index * (mBubbleSizePx + getSpaceBetweenBubbles());
+ final float bubbleFromRowLeft = index * (mBubbleSizePx + mSpaceBetweenBubbles);
return getRowLeft() + bubbleFromRowLeft;
}
- public float getOverflowBtnLeft() {
- if (mLayout == null || mLayout.getChildCount() == 0) {
- return 0;
- }
- return getBubbleLeft(mLayout.getChildCount() - 1) + mBubbleSizePx
- + getSpaceBetweenBubbles();
- }
-
/**
* When expanded, the bubbles are centered in the screen. In portrait, all available space is
* used. In landscape we have too much space so the value is restricted. This method accounts
@@ -539,7 +527,7 @@
* Determines the available screen width without the cutout.
*
* @param subtractStableInsets Whether or not stable insets should also be removed from the
- * returned width.
+ * returned width.
* @return the total screen width available accounting for cutouts and insets,
* iff {@param includeStableInsets} is true.
*/
@@ -566,38 +554,13 @@
if (mLayout == null) {
return 0;
}
-
- int bubbleCount = mLayout.getChildCount();
-
- final float totalBubbleWidth = bubbleCount * mBubbleSizePx;
- final float totalGapWidth = (bubbleCount - 1) * getSpaceBetweenBubbles();
- float rowWidth = totalGapWidth + totalBubbleWidth;
- if (mShowOverflowBtn) {
- rowWidth += getSpaceBetweenBubbles();
- rowWidth += mOverflowBtnWidth;
- }
+ float rowWidth = (mLayout.getChildCount() * mBubbleSizePx)
+ + ((mLayout.getChildCount() - 1) * mSpaceBetweenBubbles);
// This display size we're using includes the size of the insets, we want the true
// center of the display minus the notch here, which means we should include the
// stable insets (e.g. status bar, nav bar) in this calculation.
final float trueCenter = getAvailableScreenWidth(false /* subtractStableInsets */) / 2f;
- final float halfRow = rowWidth / 2f;
- final float rowLeft = trueCenter - halfRow;
- return rowLeft;
- }
-
- /**
- * @return Space between bubbles in row above expanded view.
- */
- private float getSpaceBetweenBubbles() {
- final float totalBubbleWidth = mBubblesMaxRendered * mBubbleSizePx;
- final float rowMargins = mExpandedViewPadding * 2;
- float totalGapWidth = getWidthForDisplayingBubbles() - rowMargins - totalBubbleWidth;
- if (mShowOverflowBtn) {
- totalGapWidth -= mBubbleSizePx;
- }
- final int gapCount = mBubblesMaxRendered - 1;
- final float gapWidth = totalGapWidth / gapCount;
- return gapWidth;
+ return trueCenter - (rowWidth / 2f);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIRootComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIRootComponent.java
index e14581f..e8509b3 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIRootComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIRootComponent.java
@@ -26,6 +26,7 @@
import com.android.systemui.SystemUIAppComponentFactory;
import com.android.systemui.SystemUIFactory;
import com.android.systemui.fragments.FragmentService;
+import com.android.systemui.keyguard.KeyguardSliceProvider;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.util.InjectionInflationController;
@@ -105,4 +106,9 @@
* Member injection into the supplied argument.
*/
void inject(ContentProvider contentProvider);
+
+ /**
+ * Member injection into the supplied argument.
+ */
+ void inject(KeyguardSliceProvider keyguardSliceProvider);
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
index e66a9fa..2cc3d9e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
@@ -52,13 +52,13 @@
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.SystemUIAppComponentFactory;
+import com.android.systemui.SystemUIFactory;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.policy.NextAlarmController;
-import com.android.systemui.statusbar.policy.NextAlarmControllerImpl;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.util.wakelock.SettableWakeLock;
import com.android.systemui.util.wakelock.WakeLock;
@@ -68,6 +68,8 @@
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
+import javax.inject.Inject;
+
/**
* Simple Slice provider that shows the current date.
*/
@@ -108,26 +110,31 @@
private final Handler mHandler;
private final Handler mMediaHandler;
private final AlarmManager.OnAlarmListener mUpdateNextAlarm = this::updateNextAlarm;
- private DozeParameters mDozeParameters;
+ @Inject
+ public DozeParameters mDozeParameters;
@VisibleForTesting
protected SettableWakeLock mMediaWakeLock;
- @VisibleForTesting
- protected ZenModeController mZenModeController;
+ @Inject
+ public ZenModeController mZenModeController;
private String mDatePattern;
private DateFormat mDateFormat;
private String mLastText;
private boolean mRegistered;
private String mNextAlarm;
- private NextAlarmController mNextAlarmController;
- @VisibleForTesting
- protected AlarmManager mAlarmManager;
- @VisibleForTesting
- protected ContentResolver mContentResolver;
+ @Inject
+ public NextAlarmController mNextAlarmController;
+ @Inject
+ public AlarmManager mAlarmManager;
+ @Inject
+ public ContentResolver mContentResolver;
private AlarmManager.AlarmClockInfo mNextAlarmInfo;
private PendingIntent mPendingIntent;
- protected NotificationMediaManager mMediaManager;
- private StatusBarStateController mStatusBarStateController;
- private KeyguardBypassController mKeyguardBypassController;
+ @Inject
+ public NotificationMediaManager mMediaManager;
+ @Inject
+ public StatusBarStateController mStatusBarStateController;
+ @Inject
+ public KeyguardBypassController mKeyguardBypassController;
private CharSequence mMediaTitle;
private CharSequence mMediaArtist;
protected boolean mDozing;
@@ -188,26 +195,6 @@
mMediaUri = Uri.parse(KEYGUARD_MEDIA_URI);
}
- /**
- * Initialize dependencies that don't exist during {@link android.content.ContentProvider}
- * instantiation.
- *
- * @param mediaManager {@link NotificationMediaManager} singleton.
- * @param statusBarStateController {@link StatusBarStateController} singleton.
- */
- public void initDependencies(
- NotificationMediaManager mediaManager,
- StatusBarStateController statusBarStateController,
- KeyguardBypassController keyguardBypassController,
- DozeParameters dozeParameters) {
- mMediaManager = mediaManager;
- mMediaManager.addCallback(this);
- mStatusBarStateController = statusBarStateController;
- mStatusBarStateController.addCallback(this);
- mKeyguardBypassController = keyguardBypassController;
- mDozeParameters = dozeParameters;
- }
-
@AnyThread
@Override
public Slice onBindSlice(Uri sliceUri) {
@@ -310,25 +297,19 @@
@Override
public boolean onCreateSliceProvider() {
- if (mContextAvailableCallback != null) {
- mContextAvailableCallback.onContextAvailable(getContext());
- }
+ mContextAvailableCallback.onContextAvailable(getContext());
+ inject();
synchronized (KeyguardSliceProvider.sInstanceLock) {
KeyguardSliceProvider oldInstance = KeyguardSliceProvider.sInstance;
if (oldInstance != null) {
oldInstance.onDestroy();
}
-
- mAlarmManager = getContext().getSystemService(AlarmManager.class);
- mContentResolver = getContext().getContentResolver();
- mNextAlarmController = new NextAlarmControllerImpl(getContext());
- mNextAlarmController.addCallback(this);
- mZenModeController = Dependency.get(ZenModeController.class);
- mZenModeController.addCallback(this);
mDatePattern = getContext().getString(R.string.system_ui_aod_date_pattern);
mPendingIntent = PendingIntent.getActivity(getContext(), 0, new Intent(), 0);
- mMediaWakeLock = new SettableWakeLock(WakeLock.createPartial(getContext(), "media"),
- "media");
+ mMediaManager.addCallback(this);
+ mStatusBarStateController.addCallback(this);
+ mNextAlarmController.addCallback(this);
+ mZenModeController.addCallback(this);
KeyguardSliceProvider.sInstance = this;
registerClockUpdate();
updateClockLocked();
@@ -337,6 +318,13 @@
}
@VisibleForTesting
+ protected void inject() {
+ SystemUIFactory.getInstance().getRootComponent().inject(this);
+ mMediaWakeLock = new SettableWakeLock(WakeLock.createPartial(getContext(), "media"),
+ "media");
+ }
+
+ @VisibleForTesting
protected void onDestroy() {
synchronized (KeyguardSliceProvider.sInstanceLock) {
mNextAlarmController.removeCallback(this);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
index b682cb0..3fcd1c1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
@@ -31,7 +31,6 @@
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.util.Log;
-import android.util.StatsLog;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
@@ -41,6 +40,7 @@
import android.widget.ImageView;
import android.widget.TextView;
+import com.android.internal.util.FrameworkStatsLog;
import com.android.systemui.Dependency;
import com.android.systemui.FontSizeUtils;
import com.android.systemui.R;
@@ -122,7 +122,7 @@
private void handleClick() {
showDeviceMonitoringDialog();
DevicePolicyEventLogger
- .createEvent(StatsLog.DEVICE_POLICY_EVENT__EVENT_ID__DO_USER_INFO_CLICKED)
+ .createEvent(FrameworkStatsLog.DEVICE_POLICY_EVENT__EVENT_ID__DO_USER_INFO_CLICKED)
.write();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index 976531d..d38f1b9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -79,6 +79,7 @@
private final DeviceProvisionedController mDeviceProvisionedController;
private final KeyguardStateController mKeyguardStateController;
+ private final Object mLock = new Object();
// Lazy
private NotificationEntryManager mEntryManager;
@@ -181,6 +182,7 @@
protected final Context mContext;
private final Handler mMainHandler;
protected final SparseArray<UserInfo> mCurrentProfiles = new SparseArray<>();
+ protected final ArrayList<UserInfo> mCurrentManagedProfiles = new ArrayList<>();
protected int mCurrentUserId = 0;
protected NotificationPresenter mPresenter;
@@ -300,7 +302,7 @@
}
public boolean isCurrentProfile(int userId) {
- synchronized (mCurrentProfiles) {
+ synchronized (mLock) {
return userId == UserHandle.USER_ALL || mCurrentProfiles.get(userId) != null;
}
}
@@ -417,6 +419,20 @@
return mUsersAllowingPrivateNotifications.get(userHandle);
}
+ /**
+ * If all managed profiles (work profiles) can show private data in public (secure & locked.)
+ */
+ public boolean allowsManagedPrivateNotificationsInPublic() {
+ synchronized (mLock) {
+ for (UserInfo profile : mCurrentManagedProfiles) {
+ if (!userAllowsPrivateNotificationsInPublic(profile.id)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
private boolean adminAllowsKeyguardFeature(int userHandle, int feature) {
if (userHandle == UserHandle.USER_ALL) {
return true;
@@ -495,11 +511,15 @@
}
private void updateCurrentProfilesCache() {
- synchronized (mCurrentProfiles) {
+ synchronized (mLock) {
mCurrentProfiles.clear();
+ mCurrentManagedProfiles.clear();
if (mUserManager != null) {
for (UserInfo user : mUserManager.getProfiles(mCurrentUserId)) {
mCurrentProfiles.put(user.id, user);
+ if (UserManager.USER_TYPE_PROFILE_MANAGED.equals(user.userType)) {
+ mCurrentManagedProfiles.add(user);
+ }
}
}
}
@@ -510,10 +530,29 @@
});
}
+ /**
+ * If any of the profiles are in public mode.
+ */
public boolean isAnyProfilePublicMode() {
- for (int i = mCurrentProfiles.size() - 1; i >= 0; i--) {
- if (isLockscreenPublicMode(mCurrentProfiles.valueAt(i).id)) {
- return true;
+ synchronized (mLock) {
+ for (int i = mCurrentProfiles.size() - 1; i >= 0; i--) {
+ if (isLockscreenPublicMode(mCurrentProfiles.valueAt(i).id)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * If any managed/work profiles are in public mode.
+ */
+ public boolean isAnyManagedProfilePublicMode() {
+ synchronized (mLock) {
+ for (int i = mCurrentManagedProfiles.size() - 1; i >= 0; i--) {
+ if (isLockscreenPublicMode(mCurrentManagedProfiles.get(i).id)) {
+ return true;
+ }
}
}
return false;
@@ -620,9 +659,17 @@
pw.print(" mAllowLockscreenRemoteInput=");
pw.println(mAllowLockscreenRemoteInput);
pw.print(" mCurrentProfiles=");
- for (int i = mCurrentProfiles.size() - 1; i >= 0; i--) {
- final int userId = mCurrentProfiles.valueAt(i).id;
- pw.print("" + userId + " ");
+ synchronized (mLock) {
+ for (int i = mCurrentProfiles.size() - 1; i >= 0; i--) {
+ final int userId = mCurrentProfiles.valueAt(i).id;
+ pw.print("" + userId + " ");
+ }
+ }
+ pw.print(" mCurrentManagedProfiles=");
+ synchronized (mLock) {
+ for (UserInfo userInfo : mCurrentManagedProfiles) {
+ pw.print("" + userInfo.id + " ");
+ }
}
pw.println();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
index ad1aa83..b4d0d47 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
@@ -33,7 +33,7 @@
import javax.inject.Singleton
@Singleton
-class KeyguardBypassController : Dumpable {
+open class KeyguardBypassController : Dumpable {
private val mKeyguardStateController: KeyguardStateController
private val statusBarStateController: StatusBarStateController
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 4e8442f..1726b488 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -144,7 +144,6 @@
import com.android.systemui.fragments.ExtensionFragmentListener;
import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.keyguard.DismissCallbackRegistry;
-import com.android.systemui.keyguard.KeyguardSliceProvider;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle;
@@ -794,13 +793,6 @@
mBypassHeadsUpNotifier.setUp(mEntryManager);
mBubbleController.setExpandListener(mBubbleExpandListener);
mActivityIntentHelper = new ActivityIntentHelper(mContext);
- KeyguardSliceProvider sliceProvider = KeyguardSliceProvider.getAttachedInstance();
- if (sliceProvider != null) {
- sliceProvider.initDependencies(mMediaManager, mStatusBarStateController,
- mKeyguardBypassController, mDozeParameters);
- } else {
- Log.w(TAG, "Cannot init KeyguardSliceProvider dependencies");
- }
mColorExtractor.addOnColorsChangedListener(this);
mStatusBarStateController.addCallback(this,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
index c9b6790..92c1d76 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
@@ -51,6 +51,7 @@
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.policy.NextAlarmController;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.util.wakelock.SettableWakeLock;
@@ -87,6 +88,8 @@
private SettableWakeLock mMediaWakeLock;
@Mock
private DozeParameters mDozeParameters;
+ @Mock
+ private NextAlarmController mNextAlarmController;
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private TestableKeyguardSliceProvider mProvider;
private boolean mIsZenMode;
@@ -97,9 +100,9 @@
mKeyguardUpdateMonitor = mDependency.injectMockDependency(KeyguardUpdateMonitor.class);
mIsZenMode = false;
mProvider = new TestableKeyguardSliceProvider();
+ mProvider.setContextAvailableCallback(context -> { });
mProvider.attachInfo(getContext(), null);
- mProvider.initDependencies(mNotificationMediaManager, mStatusBarStateController,
- mKeyguardBypassController, mDozeParameters);
+ reset(mContentResolver);
SliceProvider.setSpecs(new HashSet<>(Arrays.asList(SliceSpecs.LIST)));
}
@@ -254,13 +257,16 @@
}
@Override
- public boolean onCreateSliceProvider() {
- super.onCreateSliceProvider();
+ protected void inject() {
mAlarmManager = KeyguardSliceProviderTest.this.mAlarmManager;
mContentResolver = KeyguardSliceProviderTest.this.mContentResolver;
mZenModeController = KeyguardSliceProviderTest.this.mZenModeController;
mMediaWakeLock = KeyguardSliceProviderTest.this.mMediaWakeLock;
- return true;
+ mDozeParameters = KeyguardSliceProviderTest.this.mDozeParameters;
+ mNextAlarmController = KeyguardSliceProviderTest.this.mNextAlarmController;
+ mStatusBarStateController = KeyguardSliceProviderTest.this.mStatusBarStateController;
+ mKeyguardBypassController = KeyguardSliceProviderTest.this.mKeyguardBypassController;
+ mMediaManager = KeyguardSliceProviderTest.this.mNotificationMediaManager;
}
@Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
index 3a6acce..c6d57e6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
@@ -95,7 +95,9 @@
@Mock
private KeyguardStateController mKeyguardStateController;
- private int mCurrentUserId;
+ private UserInfo mCurrentUser;
+ private UserInfo mSecondaryUser;
+ private UserInfo mWorkUser;
private TestNotificationLockscreenUserManager mLockscreenUserManager;
@Before
@@ -103,10 +105,14 @@
MockitoAnnotations.initMocks(this);
mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager);
- mCurrentUserId = ActivityManager.getCurrentUser();
+ int currentUserId = ActivityManager.getCurrentUser();
+ mCurrentUser = new UserInfo(currentUserId, "", 0);
+ mSecondaryUser = new UserInfo(currentUserId + 1, "", 0);
+ mWorkUser = new UserInfo(currentUserId + 2, "" /* name */, null /* iconPath */, 0,
+ UserManager.USER_TYPE_PROFILE_MANAGED);
- when(mUserManager.getProfiles(mCurrentUserId)).thenReturn(Lists.newArrayList(
- new UserInfo(mCurrentUserId, "", 0), new UserInfo(mCurrentUserId + 1, "", 0)));
+ when(mUserManager.getProfiles(currentUserId)).thenReturn(Lists.newArrayList(
+ mCurrentUser, mSecondaryUser, mWorkUser));
mDependency.injectTestDependency(Dependency.MAIN_HANDLER,
Handler.createAsync(Looper.myLooper()));
@@ -141,15 +147,31 @@
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1);
mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false);
- assertTrue(mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(mCurrentUserId));
+ assertTrue(mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(mCurrentUser.id));
}
@Test
public void testLockScreenAllowPrivateNotificationsFalse() {
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0);
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mCurrentUser.id);
mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false);
- assertFalse(mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(mCurrentUserId));
+ assertFalse(mLockscreenUserManager.userAllowsNotificationsInPublic(mCurrentUser.id));
+ }
+
+ @Test
+ public void testLockScreenAllowsWorkPrivateNotificationsFalse() {
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mWorkUser.id);
+ mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false);
+ assertFalse(mLockscreenUserManager.allowsManagedPrivateNotificationsInPublic());
+ }
+
+ @Test
+ public void testLockScreenAllowsWorkPrivateNotificationsTrue() {
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, mWorkUser.id);
+ mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false);
+ assertTrue(mLockscreenUserManager.allowsManagedPrivateNotificationsInPublic());
}
@Test
@@ -163,16 +185,16 @@
public void testActionUserSwitchedCallsOnUserSwitched() {
Intent intent = new Intent()
.setAction(ACTION_USER_SWITCHED)
- .putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId + 1);
+ .putExtra(Intent.EXTRA_USER_HANDLE, mSecondaryUser.id);
mLockscreenUserManager.getBaseBroadcastReceiverForTest().onReceive(mContext, intent);
- verify(mPresenter, times(1)).onUserSwitched(mCurrentUserId + 1);
+ verify(mPresenter, times(1)).onUserSwitched(mSecondaryUser.id);
}
@Test
public void testIsLockscreenPublicMode() {
- assertFalse(mLockscreenUserManager.isLockscreenPublicMode(mCurrentUserId));
- mLockscreenUserManager.setLockscreenPublicMode(true, mCurrentUserId);
- assertTrue(mLockscreenUserManager.isLockscreenPublicMode(mCurrentUserId));
+ assertFalse(mLockscreenUserManager.isLockscreenPublicMode(mCurrentUser.id));
+ mLockscreenUserManager.setLockscreenPublicMode(true, mCurrentUser.id);
+ assertTrue(mLockscreenUserManager.isLockscreenPublicMode(mCurrentUser.id));
}
@Test
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index f1f2d2a..3bc93cc 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -30,7 +30,6 @@
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
@@ -88,6 +87,7 @@
import com.android.internal.util.Preconditions;
import com.android.server.location.AbstractLocationProvider;
import com.android.server.location.AbstractLocationProvider.State;
+import com.android.server.location.AppForegroundHelper;
import com.android.server.location.CallerIdentity;
import com.android.server.location.GeocoderProxy;
import com.android.server.location.GeofenceManager;
@@ -98,12 +98,12 @@
import com.android.server.location.LocationRequestStatistics;
import com.android.server.location.LocationRequestStatistics.PackageProviderKey;
import com.android.server.location.LocationRequestStatistics.PackageStatistics;
-import com.android.server.location.LocationSettingsStore;
import com.android.server.location.LocationUsageLogger;
import com.android.server.location.MockProvider;
import com.android.server.location.MockableLocationProvider;
import com.android.server.location.PassiveProvider;
-import com.android.server.location.UserInfoStore;
+import com.android.server.location.SettingsHelper;
+import com.android.server.location.UserInfoHelper;
import com.android.server.location.gnss.GnssManagerService;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
@@ -140,7 +140,6 @@
public Lifecycle(Context context) {
super(context);
mService = new LocationManagerService(context);
- LocalServices.addService(LocationManagerInternal.class, mService.new LocalService());
}
@Override
@@ -181,9 +180,6 @@
// maximum age of a location before it is no longer considered "current"
private static final long MAX_CURRENT_LOCATION_AGE_MS = 10 * 1000;
- private static final int FOREGROUND_IMPORTANCE_CUTOFF
- = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;
-
// Location Providers may sometimes deliver location updates
// slightly faster that requested - provide grace period so
// we don't unnecessarily filter events that are otherwise on
@@ -195,21 +191,23 @@
private final Object mLock = new Object();
private final Context mContext;
private final Handler mHandler;
- private final UserInfoStore mUserInfoStore;
- private final LocationSettingsStore mSettingsStore;
+ private final LocalService mLocalService;
+ private final UserInfoHelper mUserInfoHelper;
+ private final SettingsHelper mSettingsHelper;
+ private final AppForegroundHelper mAppForegroundHelper;
private final LocationUsageLogger mLocationUsageLogger;
+ @Nullable private GnssManagerService mGnssManagerService = null;
+
private final PassiveLocationProviderManager mPassiveManager;
private AppOpsManager mAppOps;
private PackageManager mPackageManager;
private PowerManager mPowerManager;
- private ActivityManager mActivityManager;
private GeofenceManager mGeofenceManager;
private LocationFudger mLocationFudger;
private GeocoderProxy mGeocodeProvider;
- @Nullable private GnssManagerService mGnssManagerService;
@GuardedBy("mLock")
private String mExtraLocationControllerPackage;
@@ -245,8 +243,13 @@
private LocationManagerService(Context context) {
mContext = context;
mHandler = FgThread.getHandler();
- mUserInfoStore = new UserInfoStore(mContext);
- mSettingsStore = new LocationSettingsStore(mContext, mHandler);
+ mLocalService = new LocalService();
+
+ LocalServices.addService(LocationManagerInternal.class, mLocalService);
+
+ mUserInfoHelper = new UserInfoHelper(mContext);
+ mSettingsHelper = new SettingsHelper(mContext, mHandler);
+ mAppForegroundHelper = new AppForegroundHelper(mContext);
mLocationUsageLogger = new LocationUsageLogger();
// set up passive provider - we do this early because it has no dependencies on system
@@ -272,17 +275,23 @@
}
private void onSystemReady() {
- mUserInfoStore.onSystemReady();
- mSettingsStore.onSystemReady();
+ mUserInfoHelper.onSystemReady();
+ mSettingsHelper.onSystemReady();
+ mAppForegroundHelper.onSystemReady();
+
+ if (GnssManagerService.isGnssSupported()) {
+ mGnssManagerService = new GnssManagerService(mContext, mSettingsHelper,
+ mAppForegroundHelper, mLocationUsageLogger);
+ mGnssManagerService.onSystemReady();
+ }
synchronized (mLock) {
mPackageManager = mContext.getPackageManager();
mAppOps = mContext.getSystemService(AppOpsManager.class);
mPowerManager = mContext.getSystemService(PowerManager.class);
- mActivityManager = mContext.getSystemService(ActivityManager.class);
mLocationFudger = new LocationFudger(mContext, mHandler);
- mGeofenceManager = new GeofenceManager(mContext, mSettingsStore);
+ mGeofenceManager = new GeofenceManager(mContext, mSettingsHelper);
PowerManagerInternal localPowerManager =
LocalServices.getService(PowerManagerInternal.class);
@@ -313,17 +322,6 @@
}
});
});
- mActivityManager.addOnUidImportanceListener(
- (uid, importance) -> {
- // listener invoked on ui thread, move to our thread to reduce risk of
- // blocking ui thread
- mHandler.post(() -> {
- synchronized (mLock) {
- onUidImportanceChangedLocked(uid, importance);
- }
- });
- },
- FOREGROUND_IMPORTANCE_CUTOFF);
localPowerManager.registerLowPowerModeObserver(ServiceType.LOCATION,
state -> {
@@ -337,26 +335,13 @@
});
mBatterySaverMode = mPowerManager.getLocationPowerSaveMode();
- mSettingsStore.addOnLocationEnabledChangedListener((userId) -> {
- synchronized (mLock) {
- onLocationModeChangedLocked(userId);
- }
- });
- mSettingsStore.addOnBackgroundThrottleIntervalChangedListener(() -> {
- synchronized (mLock) {
- onBackgroundThrottleIntervalChangedLocked();
- }
- });
- mSettingsStore.addOnBackgroundThrottlePackageWhitelistChangedListener(() -> {
- synchronized (mLock) {
- onBackgroundThrottleWhitelistChangedLocked();
- }
- });
- mSettingsStore.addOnIgnoreSettingsPackageWhitelistChangedListener(() -> {
- synchronized (mLock) {
- onIgnoreSettingsWhitelistChangedLocked();
- }
- });
+ mSettingsHelper.addOnLocationEnabledChangedListener(this::onLocationModeChanged);
+ mSettingsHelper.addOnBackgroundThrottleIntervalChangedListener(
+ this::onBackgroundThrottleIntervalChanged);
+ mSettingsHelper.addOnBackgroundThrottlePackageWhitelistChangedListener(
+ this::onBackgroundThrottleWhitelistChanged);
+ mSettingsHelper.addOnIgnoreSettingsPackageWhitelistChangedListener(
+ this::onIgnoreSettingsWhitelistChanged);
new PackageMonitor() {
@Override
@@ -367,11 +352,9 @@
}
}.register(mContext, mHandler.getLooper(), true);
- mUserInfoStore.addListener((oldUserId, newUserId) -> {
- synchronized (mLock) {
- onUserChangedLocked(oldUserId, newUserId);
- }
- });
+ mUserInfoHelper.addListener(this::onUserChanged);
+
+ mAppForegroundHelper.addListener(this::onAppForegroundChanged);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
@@ -398,7 +381,7 @@
// switching the user from null to current here performs the bulk of the initialization
// work. the user being changed will cause a reload of all user specific settings, which
// causes initialization, and propagates changes until a steady state is reached
- onUserChangedLocked(UserHandle.USER_NULL, mUserInfoStore.getCurrentUserId());
+ onUserChanged(UserHandle.USER_NULL, mUserInfoHelper.getCurrentUserId());
}
}
@@ -455,20 +438,23 @@
}
}
- @GuardedBy("mLock")
- private void onLocationModeChangedLocked(int userId) {
+ private void onLocationModeChanged(int userId) {
+ boolean enabled = mSettingsHelper.isLocationEnabled(userId);
+
if (D) {
- Log.d(TAG, "[u" + userId + "] location enabled = " + isLocationEnabledForUser(userId));
+ Log.d(TAG, "[u" + userId + "] location enabled = " + enabled);
}
- Intent intent = new Intent(LocationManager.MODE_CHANGED_ACTION)
- .putExtra(LocationManager.EXTRA_LOCATION_ENABLED, isLocationEnabledForUser(userId))
- .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY)
- .addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
- mContext.sendBroadcastAsUser(intent, UserHandle.of(userId));
+ synchronized (mLock) {
+ Intent intent = new Intent(LocationManager.MODE_CHANGED_ACTION)
+ .putExtra(LocationManager.EXTRA_LOCATION_ENABLED, enabled)
+ .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY)
+ .addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ mContext.sendBroadcastAsUser(intent, UserHandle.of(userId));
- for (LocationProviderManager manager : mProviderManagers) {
+ for (LocationProviderManager manager : mProviderManagers) {
manager.onEnabledChangedLocked(userId);
+ }
}
}
@@ -493,58 +479,55 @@
}
}
- @GuardedBy("mLock")
- private void onUidImportanceChangedLocked(int uid, int importance) {
- boolean foreground = LocationManagerServiceUtils.isImportanceForeground(importance);
- HashSet<String> affectedProviders = new HashSet<>(mRecordsByProvider.size());
- for (Entry<String, ArrayList<UpdateRecord>> entry : mRecordsByProvider.entrySet()) {
- String provider = entry.getKey();
- for (UpdateRecord record : entry.getValue()) {
- if (record.mReceiver.mCallerIdentity.mUid == uid
- && record.mIsForegroundUid != foreground) {
- if (D) {
- Log.d(TAG, "request from uid " + uid + " is now "
- + LocationManagerServiceUtils.foregroundAsString(
- foreground));
- }
- record.updateForeground(foreground);
+ private void onAppForegroundChanged(int uid, boolean foreground) {
+ synchronized (mLock) {
+ HashSet<String> affectedProviders = new HashSet<>(mRecordsByProvider.size());
+ for (Entry<String, ArrayList<UpdateRecord>> entry : mRecordsByProvider.entrySet()) {
+ String provider = entry.getKey();
+ for (UpdateRecord record : entry.getValue()) {
+ if (record.mReceiver.mCallerIdentity.mUid == uid
+ && record.mIsForegroundUid != foreground) {
+ record.updateForeground(foreground);
- if (!isThrottlingExemptLocked(record.mReceiver.mCallerIdentity)) {
- affectedProviders.add(provider);
+ if (!isThrottlingExempt(record.mReceiver.mCallerIdentity)) {
+ affectedProviders.add(provider);
+ }
}
}
}
- }
- for (String provider : affectedProviders) {
- applyRequirementsLocked(provider);
+ for (String provider : affectedProviders) {
+ applyRequirementsLocked(provider);
+ }
}
}
- @GuardedBy("mLock")
- private void onBackgroundThrottleIntervalChangedLocked() {
- for (LocationProviderManager manager : mProviderManagers) {
- applyRequirementsLocked(manager);
+ private void onBackgroundThrottleIntervalChanged() {
+ synchronized (mLock) {
+ for (LocationProviderManager manager : mProviderManagers) {
+ applyRequirementsLocked(manager);
+ }
}
}
- @GuardedBy("mLock")
- private void onBackgroundThrottleWhitelistChangedLocked() {
- for (LocationProviderManager manager : mProviderManagers) {
- applyRequirementsLocked(manager);
+ private void onBackgroundThrottleWhitelistChanged() {
+ synchronized (mLock) {
+ for (LocationProviderManager manager : mProviderManagers) {
+ applyRequirementsLocked(manager);
+ }
}
}
- @GuardedBy("lock")
- private void onIgnoreSettingsWhitelistChangedLocked() {
- for (LocationProviderManager manager : mProviderManagers) {
- applyRequirementsLocked(manager);
+ private void onIgnoreSettingsWhitelistChanged() {
+ synchronized (mLock) {
+ for (LocationProviderManager manager : mProviderManagers) {
+ applyRequirementsLocked(manager);
+ }
}
}
@GuardedBy("mLock")
private void initializeProvidersLocked() {
- if (GnssManagerService.isGnssSupported()) {
- mGnssManagerService = new GnssManagerService(this, mContext, mLocationUsageLogger);
+ if (mGnssManagerService != null) {
LocationProviderManager gnssManager = new LocationProviderManager(GPS_PROVIDER);
mProviderManagers.add(gnssManager);
gnssManager.setRealProvider(mGnssManagerService.getGnssLocationProvider());
@@ -627,19 +610,20 @@
}
}
- @GuardedBy("mLock")
- private void onUserChangedLocked(int oldUserId, int newUserId) {
+ private void onUserChanged(int oldUserId, int newUserId) {
if (D) {
Log.d(TAG, "foreground user is changing to " + newUserId);
}
- for (LocationProviderManager manager : mProviderManagers) {
- // update LOCATION_PROVIDERS_ALLOWED for best effort backwards compatibility
- mSettingsStore.setLocationProviderAllowed(manager.getName(),
- manager.isEnabled(newUserId), newUserId);
+ synchronized (mLock) {
+ for (LocationProviderManager manager : mProviderManagers) {
+ // update LOCATION_PROVIDERS_ALLOWED for best effort backwards compatibility
+ mSettingsHelper.setLocationProviderAllowed(manager.getName(),
+ manager.isEnabled(newUserId), newUserId);
- manager.onEnabledChangedLocked(oldUserId);
- manager.onEnabledChangedLocked(newUserId);
+ manager.onEnabledChangedLocked(oldUserId);
+ manager.onEnabledChangedLocked(newUserId);
+ }
}
}
@@ -778,7 +762,7 @@
// it would be more correct to call this for all users, but we know this can
// only affect the current user since providers are disabled for non-current
// users
- onEnabledChangedLocked(mUserInfoStore.getCurrentUserId());
+ onEnabledChangedLocked(mUserInfoHelper.getCurrentUserId());
}
}
@@ -787,14 +771,14 @@
}
public boolean isEnabled() {
- return isEnabled(mUserInfoStore.getCurrentUserId());
+ return isEnabled(mUserInfoHelper.getCurrentUserId());
}
public boolean isEnabled(int userId) {
synchronized (mLock) {
// normalize user id to always refer to parent since profile state is always the
// same as parent state
- userId = mUserInfoStore.getParentUserId(userId);
+ userId = mUserInfoHelper.getParentUserId(userId);
return mEnabled.get(userId, Boolean.FALSE);
}
}
@@ -808,13 +792,13 @@
// normalize user id to always refer to parent since profile state is always the same
// as parent state
- userId = mUserInfoStore.getParentUserId(userId);
+ userId = mUserInfoHelper.getParentUserId(userId);
// if any property that contributes to "enabled" here changes state, it MUST result
// in a direct or indrect call to onEnabledChangedLocked. this allows the provider to
// guarantee that it will always eventually reach the correct state.
- boolean enabled = (userId == mUserInfoStore.getCurrentUserId())
- && mSettingsStore.isLocationEnabled(userId) && mProvider.getState().allowed;
+ boolean enabled = (userId == mUserInfoHelper.getCurrentUserId())
+ && mSettingsHelper.isLocationEnabled(userId) && mProvider.getState().allowed;
if (enabled == isEnabled(userId)) {
return;
@@ -829,7 +813,7 @@
// fused and passive provider never get public updates for legacy reasons
if (!FUSED_PROVIDER.equals(mName) && !PASSIVE_PROVIDER.equals(mName)) {
// update LOCATION_PROVIDERS_ALLOWED for best effort backwards compatibility
- mSettingsStore.setLocationProviderAllowed(mName, enabled, userId);
+ mSettingsHelper.setLocationProviderAllowed(mName, enabled, userId);
Intent intent = new Intent(LocationManager.PROVIDERS_CHANGED_ACTION)
.putExtra(LocationManager.EXTRA_PROVIDER_NAME, mName)
@@ -1009,7 +993,7 @@
if (manager == null) {
continue;
}
- if (!manager.isEnabled() && !isSettingsExemptLocked(updateRecord)) {
+ if (!manager.isEnabled() && !isSettingsExempt(updateRecord)) {
continue;
}
@@ -1475,13 +1459,13 @@
ArrayList<UpdateRecord> records = mRecordsByProvider.get(manager.getName());
if (records != null) {
for (UpdateRecord record : records) {
- if (!mUserInfoStore.isCurrentUserOrProfile(
+ if (!mUserInfoHelper.isCurrentUserOrProfile(
UserHandle.getUserId(record.mReceiver.mCallerIdentity.mUid))) {
continue;
}
// requests that ignore location settings will never provide notifications
- if (isSettingsExemptLocked(record)) {
+ if (isSettingsExempt(record)) {
continue;
}
@@ -1520,14 +1504,7 @@
// if provider is not active, it should not respond to requests
if (mProviderManagers.contains(manager) && records != null && !records.isEmpty()) {
- long backgroundThrottleInterval;
-
- long identity = Binder.clearCallingIdentity();
- try {
- backgroundThrottleInterval = mSettingsStore.getBackgroundThrottleIntervalMs();
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
+ long backgroundThrottleInterval = mSettingsHelper.getBackgroundThrottleIntervalMs();
ArrayList<LocationRequest> requests = new ArrayList<>(records.size());
@@ -1540,7 +1517,7 @@
// initialize the low power mode to true and set to false if any of the records requires
providerRequest.setLowPowerMode(true);
for (UpdateRecord record : records) {
- if (!mUserInfoStore.isCurrentUserOrProfile(
+ if (!mUserInfoHelper.isCurrentUserOrProfile(
UserHandle.getUserId(record.mReceiver.mCallerIdentity.mUid))) {
continue;
}
@@ -1554,7 +1531,7 @@
final boolean isBatterySaverDisablingLocation = shouldThrottleRequests
|| (isForegroundOnlyMode && !record.mIsForegroundUid);
if (!manager.isEnabled() || isBatterySaverDisablingLocation) {
- if (isSettingsExemptLocked(record)) {
+ if (isSettingsExempt(record)) {
providerRequest.setLocationSettingsIgnored(true);
providerRequest.setLowPowerMode(false);
} else {
@@ -1567,7 +1544,7 @@
// if we're forcing location, don't apply any throttling
- if (!providerRequest.isLocationSettingsIgnored() && !isThrottlingExemptLocked(
+ if (!providerRequest.isLocationSettingsIgnored() && !isThrottlingExempt(
record.mReceiver.mCallerIdentity)) {
if (!record.mIsForegroundUid) {
interval = Math.max(interval, backgroundThrottleInterval);
@@ -1599,7 +1576,7 @@
// TODO: overflow
long thresholdInterval = (providerRequest.getInterval() + 1000) * 3 / 2;
for (UpdateRecord record : records) {
- if (mUserInfoStore.isCurrentUserOrProfile(
+ if (mUserInfoHelper.isCurrentUserOrProfile(
UserHandle.getUserId(record.mReceiver.mCallerIdentity.mUid))) {
LocationRequest locationRequest = record.mRequest;
@@ -1648,41 +1625,39 @@
@Override
public String[] getBackgroundThrottlingWhitelist() {
- return mSettingsStore.getBackgroundThrottlePackageWhitelist().toArray(new String[0]);
+ return mSettingsHelper.getBackgroundThrottlePackageWhitelist().toArray(new String[0]);
}
@Override
public String[] getIgnoreSettingsWhitelist() {
- return mSettingsStore.getIgnoreSettingsPackageWhitelist().toArray(new String[0]);
+ return mSettingsHelper.getIgnoreSettingsPackageWhitelist().toArray(new String[0]);
}
- @GuardedBy("mLock")
- public boolean isThrottlingExemptLocked(CallerIdentity callerIdentity) {
+ private boolean isThrottlingExempt(CallerIdentity callerIdentity) {
if (callerIdentity.mUid == Process.SYSTEM_UID) {
return true;
}
- if (mSettingsStore.getBackgroundThrottlePackageWhitelist().contains(
+ if (mSettingsHelper.getBackgroundThrottlePackageWhitelist().contains(
callerIdentity.mPackageName)) {
return true;
}
- return isProviderPackage(callerIdentity.mPackageName);
+ return mLocalService.isProviderPackage(callerIdentity.mPackageName);
}
- @GuardedBy("mLock")
- private boolean isSettingsExemptLocked(UpdateRecord record) {
+ private boolean isSettingsExempt(UpdateRecord record) {
if (!record.mRealRequest.isLocationSettingsIgnored()) {
return false;
}
- if (mSettingsStore.getIgnoreSettingsPackageWhitelist().contains(
+ if (mSettingsHelper.getIgnoreSettingsPackageWhitelist().contains(
record.mReceiver.mCallerIdentity.mPackageName)) {
return true;
}
- return isProviderPackage(record.mReceiver.mCallerIdentity.mPackageName);
+ return mLocalService.isProviderPackage(record.mReceiver.mCallerIdentity.mPackageName);
}
@@ -1705,10 +1680,7 @@
mRealRequest = request;
mRequest = request;
mReceiver = receiver;
- mIsForegroundUid =
- LocationManagerServiceUtils.isImportanceForeground(
- mActivityManager.getPackageImportance(
- mReceiver.mCallerIdentity.mPackageName));
+ mIsForegroundUid = mAppForegroundHelper.isAppForeground(mReceiver.mCallerIdentity.mUid);
if (D && receiver.mCallerIdentity.mPid == Process.myPid()) {
mStackTrace = new Throwable();
@@ -1753,7 +1725,7 @@
mReceiver.isListener(),
mReceiver.isPendingIntent(),
/* geofence= */ null,
- mActivityManager.getPackageImportance(packageName));
+ mAppForegroundHelper.getImportance(mReceiver.mCallerIdentity.mUid));
// remove from mRecordsByProvider
ArrayList<UpdateRecord> globalRecords = mRecordsByProvider.get(this.mProvider);
@@ -1923,7 +1895,7 @@
LocationStatsEnums.API_REQUEST_LOCATION_UPDATES,
packageName, request, listener != null, intent != null,
/* geofence= */ null,
- mActivityManager.getPackageImportance(packageName));
+ mAppForegroundHelper.getImportance(uid));
Receiver receiver;
if (intent != null) {
@@ -1961,7 +1933,7 @@
Log.d(TAG, "request " + Integer.toHexString(System.identityHashCode(receiver))
+ " " + name + " " + request + " from " + packageName + "(" + uid + " "
+ (record.mIsForegroundUid ? "foreground" : "background")
- + (isThrottlingExemptLocked(receiver.mCallerIdentity)
+ + (isThrottlingExempt(receiver.mCallerIdentity)
? " [whitelisted]" : "") + ")");
}
@@ -1970,7 +1942,7 @@
oldRecord.disposeLocked(false);
}
- if (!manager.isEnabled() && !isSettingsExemptLocked(record)) {
+ if (!manager.isEnabled() && !isSettingsExempt(record)) {
// Notify the listener that updates are currently disabled - but only if the request
// does not ignore location settings
receiver.callProviderEnabledLocked(name, false);
@@ -2060,7 +2032,7 @@
final int uid = Binder.getCallingUid();
final long identity = Binder.clearCallingIdentity();
try {
- if (mSettingsStore.isLocationPackageBlacklisted(UserHandle.getUserId(uid),
+ if (mSettingsHelper.isLocationPackageBlacklisted(UserHandle.getUserId(uid),
packageName)) {
if (D) {
Log.d(TAG, "not returning last loc for blacklisted app: "
@@ -2077,8 +2049,8 @@
if (manager == null) return null;
// only the current user or location providers may get location this way
- if (!mUserInfoStore.isCurrentUserOrProfile(UserHandle.getUserId(uid))
- && !isProviderPackage(packageName)) {
+ if (!mUserInfoHelper.isCurrentUserOrProfile(UserHandle.getUserId(uid))
+ && !mLocalService.isProviderPackage(packageName)) {
return null;
}
@@ -2102,7 +2074,7 @@
String op = resolutionLevelToOpStr(allowedResolutionLevel);
long locationAgeMs = TimeUnit.NANOSECONDS.toMillis(
SystemClock.elapsedRealtime() - location.getElapsedRealtimeNanos());
- if (locationAgeMs > mSettingsStore.getMaxLastLocationAgeMs()
+ if (locationAgeMs > mSettingsHelper.getMaxLastLocationAgeMs()
&& (mAppOps.unsafeCheckOp(op, uid, packageName)
== AppOpsManager.MODE_FOREGROUND)) {
return null;
@@ -2145,29 +2117,21 @@
long locationAgeMs = TimeUnit.NANOSECONDS.toMillis(
SystemClock.elapsedRealtimeNanos() - lastLocation.getElapsedRealtimeNanos());
- long identity = Binder.clearCallingIdentity();
- try {
- if (locationAgeMs < MAX_CURRENT_LOCATION_AGE_MS) {
- try {
- listener.onLocationChanged(lastLocation);
- return true;
- } catch (RemoteException e) {
- Log.w(TAG, e);
- return false;
- }
+ if (locationAgeMs < MAX_CURRENT_LOCATION_AGE_MS) {
+ try {
+ listener.onLocationChanged(lastLocation);
+ return true;
+ } catch (RemoteException e) {
+ Log.w(TAG, e);
+ return false;
}
+ }
- // packageName already validated by getLastLocation() call above
- boolean foreground = LocationManagerServiceUtils.isImportanceForeground(
- mActivityManager.getPackageImportance(packageName));
- if (!foreground) {
- if (locationAgeMs < mSettingsStore.getBackgroundThrottleIntervalMs()) {
- // not allowed to request new locations, so we can't return anything
- return false;
- }
+ if (!mAppForegroundHelper.isAppForeground(Binder.getCallingUid())) {
+ if (locationAgeMs < mSettingsHelper.getBackgroundThrottleIntervalMs()) {
+ // not allowed to request new locations, so we can't return anything
+ return false;
}
- } finally {
- Binder.restoreCallingIdentity(identity);
}
}
@@ -2252,20 +2216,19 @@
Log.w(TAG, "proximity alerts are currently available only to the primary user");
return;
}
+
+ mLocationUsageLogger.logLocationApiUsage(
+ LocationStatsEnums.USAGE_STARTED,
+ LocationStatsEnums.API_REQUEST_GEOFENCE,
+ packageName,
+ request,
+ /* hasListener= */ false,
+ true,
+ geofence,
+ mAppForegroundHelper.getImportance(uid));
+
long identity = Binder.clearCallingIdentity();
try {
- synchronized (mLock) {
- mLocationUsageLogger.logLocationApiUsage(
- LocationStatsEnums.USAGE_STARTED,
- LocationStatsEnums.API_REQUEST_GEOFENCE,
- packageName,
- request,
- /* hasListener= */ false,
- true,
- geofence,
- mActivityManager.getPackageImportance(packageName));
- }
-
mGeofenceManager.addFence(sanitizedRequest, geofence, intent, allowedResolutionLevel,
uid, packageName, featureId, listenerIdentifier);
} finally {
@@ -2282,20 +2245,19 @@
if (D) Log.d(TAG, "removeGeofence: " + geofence + " " + intent);
+ mLocationUsageLogger.logLocationApiUsage(
+ LocationStatsEnums.USAGE_ENDED,
+ LocationStatsEnums.API_REQUEST_GEOFENCE,
+ packageName,
+ /* LocationRequest= */ null,
+ /* hasListener= */ false,
+ true,
+ geofence,
+ mAppForegroundHelper.getImportance(Binder.getCallingUid()));
+
// geo-fence manager uses the public location API, need to clear identity
long identity = Binder.clearCallingIdentity();
try {
- synchronized (mLock) {
- mLocationUsageLogger.logLocationApiUsage(
- LocationStatsEnums.USAGE_ENDED,
- LocationStatsEnums.API_REQUEST_GEOFENCE,
- packageName,
- /* LocationRequest= */ null,
- /* hasListener= */ false,
- true,
- geofence,
- mActivityManager.getPackageImportance(packageName));
- }
mGeofenceManager.removeFence(geofence, intent);
} finally {
Binder.restoreCallingIdentity(identity);
@@ -2392,12 +2354,6 @@
}
@Override
- public boolean sendNiResponse(int notifId, int userResponse) {
- return mGnssManagerService != null && mGnssManagerService.sendNiResponse(notifId,
- userResponse);
- }
-
- @Override
public ProviderProperties getProviderProperties(String providerName) {
LocationProviderManager manager = getLocationProviderManager(providerName);
if (manager == null) {
@@ -2408,20 +2364,13 @@
@Override
public boolean isProviderPackage(String packageName) {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_DEVICE_CONFIG,
- Manifest.permission.READ_DEVICE_CONFIG + " permission required");
- for (LocationProviderManager manager : mProviderManagers) {
- if (manager.getPackages().contains(packageName)) {
- return true;
- }
- }
- return false;
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_DEVICE_CONFIG, null);
+ return mLocalService.isProviderPackage(packageName);
}
@Override
public List<String> getProviderPackages(String providerName) {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_DEVICE_CONFIG,
- Manifest.permission.READ_DEVICE_CONFIG + " permission required");
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_DEVICE_CONFIG, null);
LocationProviderManager manager = getLocationProviderManager(providerName);
return manager == null ? Collections.emptyList() : new ArrayList<>(manager.getPackages());
}
@@ -2461,28 +2410,19 @@
@Override
public boolean isLocationEnabledForUser(int userId) {
- // Check INTERACT_ACROSS_USERS permission if userId is not current user id.
if (UserHandle.getCallingUserId() != userId) {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.INTERACT_ACROSS_USERS,
- "Requires INTERACT_ACROSS_USERS permission");
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.INTERACT_ACROSS_USERS,
+ null);
}
- long identity = Binder.clearCallingIdentity();
- try {
- return mSettingsStore.isLocationEnabled(userId);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
+ return mSettingsHelper.isLocationEnabled(userId);
}
@Override
public boolean isProviderEnabledForUser(String providerName, int userId) {
- // Check INTERACT_ACROSS_USERS permission if userId is not current user id.
if (UserHandle.getCallingUserId() != userId) {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.INTERACT_ACROSS_USERS,
- "Requires INTERACT_ACROSS_USERS permission");
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.INTERACT_ACROSS_USERS,
+ null);
}
// Fused provider is accessed indirectly via criteria rather than the provider-based APIs,
@@ -2593,12 +2533,12 @@
Receiver receiver = r.mReceiver;
boolean receiverDead = false;
- if (!manager.isEnabled() && !isSettingsExemptLocked(r)) {
+ if (!manager.isEnabled() && !isSettingsExempt(r)) {
continue;
}
int receiverUserId = UserHandle.getUserId(receiver.mCallerIdentity.mUid);
- if (!mUserInfoStore.isCurrentUserOrProfile(receiverUserId)
+ if (!mUserInfoHelper.isCurrentUserOrProfile(receiverUserId)
&& !isProviderPackage(receiver.mCallerIdentity.mPackageName)) {
if (D) {
Log.d(TAG, "skipping loc update for background user " + receiverUserId +
@@ -2607,7 +2547,7 @@
continue;
}
- if (mSettingsStore.isLocationPackageBlacklisted(receiverUserId,
+ if (mSettingsHelper.isLocationPackageBlacklisted(receiverUserId,
receiver.mCallerIdentity.mPackageName)) {
if (D) {
Log.d(TAG, "skipping loc update for blacklisted app: " +
@@ -2855,12 +2795,12 @@
ipw.println("User Info:");
ipw.increaseIndent();
- mUserInfoStore.dump(fd, ipw, args);
+ mUserInfoHelper.dump(fd, ipw, args);
ipw.decreaseIndent();
ipw.println("Location Settings:");
ipw.increaseIndent();
- mSettingsStore.dump(fd, ipw, args);
+ mSettingsHelper.dump(fd, ipw, args);
ipw.decreaseIndent();
ipw.println("Battery Saver Location Mode: "
@@ -2960,5 +2900,22 @@
}
}
}
+
+ @Override
+ public boolean isProviderPackage(String packageName) {
+ for (LocationProviderManager manager : mProviderManagers) {
+ if (manager.getPackages().contains(packageName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void sendNiResponse(int notifId, int userResponse) {
+ if (mGnssManagerService != null) {
+ mGnssManagerService.sendNiResponse(notifId, userResponse);
+ }
+ }
}
}
diff --git a/services/core/java/com/android/server/LocationManagerServiceUtils.java b/services/core/java/com/android/server/LocationManagerServiceUtils.java
index 9c8ac19..372e91e 100644
--- a/services/core/java/com/android/server/LocationManagerServiceUtils.java
+++ b/services/core/java/com/android/server/LocationManagerServiceUtils.java
@@ -17,8 +17,6 @@
package com.android.server;
import android.annotation.NonNull;
-import android.app.ActivityManager;
-import android.content.Context;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
@@ -91,12 +89,8 @@
/**
* Link listener (i.e. callback) to a binder, so that it will be called upon binder's death.
- *
- * @param binder that calls listener upon death
- * @return true if listener is successfully linked to binder, false otherwise
*/
- public boolean linkToListenerDeathNotificationLocked(
- IBinder binder) {
+ public boolean linkToListenerDeathNotificationLocked(IBinder binder) {
try {
binder.linkToDeath(this, 0 /* flags */);
return true;
@@ -110,54 +104,13 @@
/**
* Unlink death listener (i.e. callback) from binder.
- *
- * @param binder that calls listener upon death
- * @return true if binder is successfully unlinked from binder, false otherwise
*/
- public boolean unlinkFromListenerDeathNotificationLocked(
- IBinder binder) {
+ public void unlinkFromListenerDeathNotificationLocked(IBinder binder) {
try {
binder.unlinkToDeath(this, 0 /* flags */);
- return true;
} catch (NoSuchElementException e) {
- // if the death callback isn't connected (it should be...), log error,
- // swallow the exception and return
Log.w(TAG, "Could not unlink " + mListenerName + " death callback.", e);
- return false;
}
}
-
- }
-
- /**
- * Convert boolean foreground into "foreground" or "background" string.
- *
- * @param foreground boolean indicating foreground
- * @return "foreground" string if true, false otherwise
- */
- public static String foregroundAsString(boolean foreground) {
- return foreground ? "foreground" : "background";
- }
-
-
- /**
- * Classifies importance level as foreground or not.
- *
- * @param importance level as int
- * @return boolean indicating if importance level is foreground or greater
- */
- public static boolean isImportanceForeground(int importance) {
- return importance <= ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;
- }
-
- /**
- * Get package importance level.
- *
- * @param packageName package name
- * @return package importance level as int
- */
- public static int getPackageImportance(String packageName, Context context) {
- return ((ActivityManager) context.getSystemService(
- Context.ACTIVITY_SERVICE)).getPackageImportance(packageName);
}
}
diff --git a/services/core/java/com/android/server/MmsServiceBroker.java b/services/core/java/com/android/server/MmsServiceBroker.java
index 9b1326b..043f657 100644
--- a/services/core/java/com/android/server/MmsServiceBroker.java
+++ b/services/core/java/com/android/server/MmsServiceBroker.java
@@ -128,13 +128,15 @@
@Override
public void sendMessage(int subId, String callingPkg, Uri contentUri, String locationUrl,
- Bundle configOverrides, PendingIntent sentIntent) throws RemoteException {
+ Bundle configOverrides, PendingIntent sentIntent, long messageId)
+ throws RemoteException {
returnPendingIntentWithError(sentIntent);
}
@Override
public void downloadMessage(int subId, String callingPkg, String locationUrl,
- Uri contentUri, Bundle configOverrides, PendingIntent downloadedIntent)
+ Uri contentUri, Bundle configOverrides, PendingIntent downloadedIntent,
+ long messageId)
throws RemoteException {
returnPendingIntentWithError(downloadedIntent);
}
@@ -329,7 +331,8 @@
@Override
public void sendMessage(int subId, String callingPkg, Uri contentUri,
- String locationUrl, Bundle configOverrides, PendingIntent sentIntent)
+ String locationUrl, Bundle configOverrides, PendingIntent sentIntent,
+ long messageId)
throws RemoteException {
Slog.d(TAG, "sendMessage() by " + callingPkg);
mContext.enforceCallingPermission(Manifest.permission.SEND_SMS, "Send MMS message");
@@ -343,13 +346,13 @@
Intent.FLAG_GRANT_READ_URI_PERMISSION,
subId);
getServiceGuarded().sendMessage(subId, callingPkg, contentUri, locationUrl,
- configOverrides, sentIntent);
+ configOverrides, sentIntent, messageId);
}
@Override
public void downloadMessage(int subId, String callingPkg, String locationUrl,
Uri contentUri, Bundle configOverrides,
- PendingIntent downloadedIntent) throws RemoteException {
+ PendingIntent downloadedIntent, long messageId) throws RemoteException {
Slog.d(TAG, "downloadMessage() by " + callingPkg);
mContext.enforceCallingPermission(Manifest.permission.RECEIVE_MMS,
"Download MMS message");
@@ -364,7 +367,7 @@
subId);
getServiceGuarded().downloadMessage(subId, callingPkg, locationUrl, contentUri,
- configOverrides, downloadedIntent);
+ configOverrides, downloadedIntent, messageId);
}
@Override
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 8451d6b..d720105 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -58,6 +58,8 @@
private static final String KEY_CONTENT_PROVIDER_RETAIN_TIME = "content_provider_retain_time";
private static final String KEY_GC_TIMEOUT = "gc_timeout";
private static final String KEY_GC_MIN_INTERVAL = "gc_min_interval";
+ private static final String KEY_FORCE_BACKGROUND_CHECK_ON_RESTRICTED_APPS =
+ "force_bg_check_on_restricted";
private static final String KEY_FULL_PSS_MIN_INTERVAL = "full_pss_min_interval";
private static final String KEY_FULL_PSS_LOWERED_INTERVAL = "full_pss_lowered_interval";
private static final String KEY_POWER_CHECK_INTERVAL = "power_check_interval";
@@ -96,6 +98,7 @@
private static final long DEFAULT_GC_TIMEOUT = 5*1000;
private static final long DEFAULT_GC_MIN_INTERVAL = 60*1000;
private static final long DEFAULT_FULL_PSS_MIN_INTERVAL = 20*60*1000;
+ private static final boolean DEFAULT_FORCE_BACKGROUND_CHECK_ON_RESTRICTED_APPS = true;
private static final long DEFAULT_FULL_PSS_LOWERED_INTERVAL = 5*60*1000;
private static final long DEFAULT_POWER_CHECK_INTERVAL = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
private static final int DEFAULT_POWER_CHECK_MAX_CPU_1 = 25;
@@ -177,6 +180,14 @@
// The minimum amount of time between successive GC requests for a process.
long GC_MIN_INTERVAL = DEFAULT_GC_MIN_INTERVAL;
+ /**
+ * Whether or not Background Check should be forced on any apps in the
+ * {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED} bucket,
+ * regardless of target SDK version.
+ */
+ boolean FORCE_BACKGROUND_CHECK_ON_RESTRICTED_APPS =
+ DEFAULT_FORCE_BACKGROUND_CHECK_ON_RESTRICTED_APPS;
+
// The minimum amount of time between successive PSS requests for a process.
long FULL_PSS_MIN_INTERVAL = DEFAULT_FULL_PSS_MIN_INTERVAL;
@@ -380,6 +391,9 @@
case KEY_IMPERCEPTIBLE_KILL_EXEMPT_PROC_STATES:
updateImperceptibleKillExemptions();
break;
+ case KEY_FORCE_BACKGROUND_CHECK_ON_RESTRICTED_APPS:
+ updateForceRestrictedBackgroundCheck();
+ break;
default:
break;
}
@@ -427,6 +441,7 @@
updateMaxCachedProcesses();
updateActivityStartsLoggingEnabled();
updateBackgroundActivityStarts();
+ updateForceRestrictedBackgroundCheck();
updateForegroundServiceStartsLoggingEnabled();
updateBackgroundFgsStartsRestriction();
updateOomAdjUpdatePolicy();
@@ -571,6 +586,13 @@
== OOMADJ_UPDATE_POLICY_QUICK;
}
+ private void updateForceRestrictedBackgroundCheck() {
+ FORCE_BACKGROUND_CHECK_ON_RESTRICTED_APPS = DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ KEY_FORCE_BACKGROUND_CHECK_ON_RESTRICTED_APPS,
+ DEFAULT_FORCE_BACKGROUND_CHECK_ON_RESTRICTED_APPS);
+ }
+
private void updateImperceptibleKillExemptions() {
IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.clear();
IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.addAll(mDefaultImperceptibleKillExemptPackages);
@@ -658,6 +680,8 @@
pw.println(GC_TIMEOUT);
pw.print(" "); pw.print(KEY_GC_MIN_INTERVAL); pw.print("=");
pw.println(GC_MIN_INTERVAL);
+ pw.print(" "); pw.print(KEY_FORCE_BACKGROUND_CHECK_ON_RESTRICTED_APPS); pw.print("=");
+ pw.println(FORCE_BACKGROUND_CHECK_ON_RESTRICTED_APPS);
pw.print(" "); pw.print(KEY_FULL_PSS_MIN_INTERVAL); pw.print("=");
pw.println(FULL_PSS_MIN_INTERVAL);
pw.print(" "); pw.print(KEY_FULL_PSS_LOWERED_INTERVAL); pw.print("=");
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 4c5f705..2b160dd 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -184,6 +184,7 @@
import android.app.backup.IBackupManager;
import android.app.usage.UsageEvents;
import android.app.usage.UsageEvents.Event;
+import android.app.usage.UsageStatsManager;
import android.app.usage.UsageStatsManagerInternal;
import android.appwidget.AppWidgetManager;
import android.content.AutofillOptions;
@@ -6051,6 +6052,11 @@
}
}
+ private boolean isInRestrictedBucket(int userId, String packageName, long nowElapsed) {
+ return UsageStatsManager.STANDBY_BUCKET_RESTRICTED
+ <= mUsageStatsService.getAppStandbyBucket(packageName, userId, nowElapsed);
+ }
+
// Unified app-op and target sdk check
int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
// Apps that target O+ are always subject to background check
@@ -6060,7 +6066,17 @@
}
return ActivityManager.APP_START_MODE_DELAYED_RIGID;
}
- // ...and legacy apps get an AppOp check
+ // It's a legacy app. If it's in the RESTRICTED bucket, always restrict on battery.
+ if (mOnBattery // Short-circuit in common case.
+ && mConstants.FORCE_BACKGROUND_CHECK_ON_RESTRICTED_APPS
+ && isInRestrictedBucket(
+ UserHandle.getUserId(uid), packageName, SystemClock.elapsedRealtime())) {
+ if (DEBUG_BACKGROUND_CHECK) {
+ Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " in RESTRICTED bucket");
+ }
+ return ActivityManager.APP_START_MODE_DELAYED;
+ }
+ // Not in the RESTRICTED bucket so policy is based on AppOp check.
int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
uid, packageName, null, false, "");
if (DEBUG_BACKGROUND_CHECK) {
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 8dd3242..be5350f 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -60,12 +60,12 @@
import android.text.TextUtils;
import android.util.Pair;
import android.util.Slog;
-import android.util.StatsLog;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.SomeArgs;
import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.util.FrameworkStatsLog;
import com.android.server.SystemService;
import java.util.ArrayList;
@@ -1142,17 +1142,17 @@
+ ", Client: " + BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT
+ ", RequireConfirmation: "
+ mCurrentAuthSession.mRequireConfirmation
- + ", State: " + StatsLog.BIOMETRIC_AUTHENTICATED__STATE__CONFIRMED
+ + ", State: " + FrameworkStatsLog.BIOMETRIC_AUTHENTICATED__STATE__CONFIRMED
+ ", Latency: " + latency);
}
- StatsLog.write(StatsLog.BIOMETRIC_AUTHENTICATED,
+ FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_AUTHENTICATED,
statsModality(),
mCurrentAuthSession.mUserId,
mCurrentAuthSession.isCrypto(),
BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
mCurrentAuthSession.mRequireConfirmation,
- StatsLog.BIOMETRIC_AUTHENTICATED__STATE__CONFIRMED,
+ FrameworkStatsLog.BIOMETRIC_AUTHENTICATED__STATE__CONFIRMED,
latency,
mInjector.isDebugEnabled(getContext(), mCurrentAuthSession.mUserId));
} else {
@@ -1174,7 +1174,7 @@
+ ", Latency: " + latency);
}
// Auth canceled
- StatsLog.write(StatsLog.BIOMETRIC_ERROR_OCCURRED,
+ FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_ERROR_OCCURRED,
statsModality(),
mCurrentAuthSession.mUserId,
mCurrentAuthSession.isCrypto(),
diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
index 60f0e8e..687d935 100644
--- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
+++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
@@ -51,10 +51,10 @@
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Slog;
-import android.util.StatsLog;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.util.FrameworkStatsLog;
import com.android.server.SystemService;
import java.util.ArrayList;
@@ -371,7 +371,7 @@
+ identifier.getName());
mUtils.removeBiometricForUser(getContext(),
getTargetUserId(), identifier.getBiometricId());
- StatsLog.write(StatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED,
+ FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED,
statsModality(),
BiometricsProtoEnums.ISSUE_UNKNOWN_TEMPLATE_ENROLLED_FRAMEWORK);
}
@@ -551,7 +551,7 @@
+ " failed to respond to cancel, starting client "
+ (mPendingClient != null ? mPendingClient.getOwnerString() : "null"));
- StatsLog.write(StatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED,
+ FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED,
statsModality(), BiometricsProtoEnums.ISSUE_CANCEL_TIMED_OUT);
mCurrentClient = null;
@@ -673,8 +673,8 @@
0 /*vendorCode */);
});
- StatsLog.write(StatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED, statsModality(),
- BiometricsProtoEnums.ISSUE_HAL_DEATH);
+ FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED,
+ statsModality(), BiometricsProtoEnums.ISSUE_HAL_DEATH);
}
protected ClientMonitor getCurrentClient() {
@@ -1249,7 +1249,7 @@
template.mIdentifier.getBiometricId(), 0 /* groupId */, template.mUserId,
restricted, getContext().getPackageName());
removeInternal(client);
- StatsLog.write(StatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED,
+ FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED,
statsModality(),
BiometricsProtoEnums.ISSUE_UNKNOWN_TEMPLATE_ENROLLED_HAL);
} else {
diff --git a/services/core/java/com/android/server/biometrics/LoggableMonitor.java b/services/core/java/com/android/server/biometrics/LoggableMonitor.java
index ecf3864..c03c77f 100644
--- a/services/core/java/com/android/server/biometrics/LoggableMonitor.java
+++ b/services/core/java/com/android/server/biometrics/LoggableMonitor.java
@@ -21,7 +21,8 @@
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.face.FaceManager;
import android.util.Slog;
-import android.util.StatsLog;
+
+import com.android.internal.util.FrameworkStatsLog;
/**
* Abstract class that adds logging functionality to the ClientMonitor classes.
@@ -86,7 +87,7 @@
+ ", AcquiredInfo: " + acquiredInfo
+ ", VendorCode: " + vendorCode);
}
- StatsLog.write(StatsLog.BIOMETRIC_ACQUIRED,
+ FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_ACQUIRED,
statsModality(),
targetUserId,
isCryptoOperation(),
@@ -114,7 +115,7 @@
} else {
Slog.v(TAG, "Error latency: " + latency);
}
- StatsLog.write(StatsLog.BIOMETRIC_ERROR_OCCURRED,
+ FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_ERROR_OCCURRED,
statsModality(),
targetUserId,
isCryptoOperation(),
@@ -128,15 +129,15 @@
protected final void logOnAuthenticated(Context context, boolean authenticated,
boolean requireConfirmation, int targetUserId, boolean isBiometricPrompt) {
- int authState = StatsLog.BIOMETRIC_AUTHENTICATED__STATE__UNKNOWN;
+ int authState = FrameworkStatsLog.BIOMETRIC_AUTHENTICATED__STATE__UNKNOWN;
if (!authenticated) {
- authState = StatsLog.BIOMETRIC_AUTHENTICATED__STATE__REJECTED;
+ authState = FrameworkStatsLog.BIOMETRIC_AUTHENTICATED__STATE__REJECTED;
} else {
// Authenticated
if (isBiometricPrompt && requireConfirmation) {
- authState = StatsLog.BIOMETRIC_AUTHENTICATED__STATE__PENDING_CONFIRMATION;
+ authState = FrameworkStatsLog.BIOMETRIC_AUTHENTICATED__STATE__PENDING_CONFIRMATION;
} else {
- authState = StatsLog.BIOMETRIC_AUTHENTICATED__STATE__CONFIRMED;
+ authState = FrameworkStatsLog.BIOMETRIC_AUTHENTICATED__STATE__CONFIRMED;
}
}
@@ -157,7 +158,7 @@
Slog.v(TAG, "Authentication latency: " + latency);
}
- StatsLog.write(StatsLog.BIOMETRIC_AUTHENTICATED,
+ FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_AUTHENTICATED,
statsModality(),
targetUserId,
isCryptoOperation(),
@@ -179,7 +180,7 @@
Slog.v(TAG, "Enroll latency: " + latency);
}
- StatsLog.write(StatsLog.BIOMETRIC_ENROLLED,
+ FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_ENROLLED,
statsModality(),
targetUserId,
latency,
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index 4d5af9a..47bb5f3 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -30,7 +30,6 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Slog;
-import android.util.StatsLog;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.compat.AndroidBuildClassifier;
@@ -40,6 +39,7 @@
import com.android.internal.compat.IOverrideValidator;
import com.android.internal.compat.IPlatformCompat;
import com.android.internal.util.DumpUtils;
+import com.android.internal.util.FrameworkStatsLog;
import com.android.server.LocalServices;
import java.io.FileDescriptor;
@@ -59,7 +59,7 @@
public PlatformCompat(Context context) {
mContext = context;
mChangeReporter = new ChangeReporter(
- StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__SOURCE__SYSTEM_SERVER);
+ FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__SOURCE__SYSTEM_SERVER);
mCompatConfig = CompatConfig.create(new AndroidBuildClassifier(), mContext);
}
@@ -67,7 +67,7 @@
PlatformCompat(Context context, CompatConfig compatConfig) {
mContext = context;
mChangeReporter = new ChangeReporter(
- StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__SOURCE__SYSTEM_SERVER);
+ FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__SOURCE__SYSTEM_SERVER);
mCompatConfig = compatConfig;
}
@@ -75,7 +75,7 @@
public void reportChange(long changeId, ApplicationInfo appInfo) {
checkCompatChangeLogPermission();
reportChange(changeId, appInfo.uid,
- StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED);
+ FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED);
}
@Override
@@ -91,7 +91,8 @@
@Override
public void reportChangeByUid(long changeId, int uid) {
checkCompatChangeLogPermission();
- reportChange(changeId, uid, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED);
+ reportChange(changeId, uid,
+ FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED);
}
@Override
@@ -99,11 +100,11 @@
checkCompatChangeReadPermission();
if (mCompatConfig.isChangeEnabled(changeId, appInfo)) {
reportChange(changeId, appInfo.uid,
- StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__ENABLED);
+ FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__ENABLED);
return true;
}
reportChange(changeId, appInfo.uid,
- StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__DISABLED);
+ FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__DISABLED);
return false;
}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
index 9c42152..9f76e1e 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
@@ -34,6 +34,16 @@
*/
public abstract class InputMethodManagerInternal {
/**
+ * Listener for input method list changed events.
+ */
+ public interface InputMethodListListener {
+ /**
+ * Called with the list of the installed IMEs when it's updated.
+ */
+ void onInputMethodListUpdated(List<InputMethodInfo> info, @UserIdInt int userId);
+ }
+
+ /**
* Called by the power manager to tell the input method manager whether it
* should start watching for wake events.
*/
@@ -85,6 +95,11 @@
public abstract boolean switchToInputMethod(String imeId, @UserIdInt int userId);
/**
+ * Registers a new {@link InputMethodListListener}.
+ */
+ public abstract void registerInputMethodListListener(InputMethodListListener listener);
+
+ /**
* Fake implementation of {@link InputMethodManagerInternal}. All the methods do nothing.
*/
private static final InputMethodManagerInternal NOP =
@@ -117,6 +132,10 @@
public boolean switchToInputMethod(String imeId, int userId) {
return false;
}
+
+ @Override
+ public void registerInputMethodListListener(InputMethodListListener listener) {
+ }
};
/**
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 15698e9..47622f3 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -154,6 +154,7 @@
import com.android.server.EventLogTags;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.inputmethod.InputMethodManagerInternal.InputMethodListListener;
import com.android.server.inputmethod.InputMethodSubtypeSwitchingController.ImeSubtypeListItem;
import com.android.server.inputmethod.InputMethodUtils.InputMethodSettings;
import com.android.server.statusbar.StatusBarManagerService;
@@ -172,6 +173,7 @@
import java.util.List;
import java.util.Locale;
import java.util.WeakHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -214,6 +216,7 @@
static final int MSG_HARD_KEYBOARD_SWITCH_CHANGED = 4000;
static final int MSG_SYSTEM_UNLOCK_USER = 5000;
+ static final int MSG_DISPATCH_ON_INPUT_METHOD_LIST_UPDATED = 5010;
static final int MSG_INLINE_SUGGESTIONS_REQUEST = 6000;
@@ -689,6 +692,13 @@
private final String mSlotIme;
/**
+ * Registered {@link InputMethodListListeners}.
+ * This variable can be accessed from both of MainThread and BinderThread.
+ */
+ private final CopyOnWriteArrayList<InputMethodListListener> mInputMethodListListeners =
+ new CopyOnWriteArrayList<>();
+
+ /**
* Internal state snapshot when {@link #MSG_START_INPUT} message is about to be posted to the
* internal message queue. Any subsequent state change inside {@link InputMethodManagerService}
* will not affect those tasks that are already posted.
@@ -3946,10 +3956,18 @@
case MSG_HARD_KEYBOARD_SWITCH_CHANGED:
mHardKeyboardListener.handleHardKeyboardStatusChange(msg.arg1 == 1);
return true;
- case MSG_SYSTEM_UNLOCK_USER:
+ case MSG_SYSTEM_UNLOCK_USER: {
final int userId = msg.arg1;
onUnlockUser(userId);
return true;
+ }
+ case MSG_DISPATCH_ON_INPUT_METHOD_LIST_UPDATED: {
+ final int userId = msg.arg1;
+ final List<InputMethodInfo> imes = (List<InputMethodInfo>) msg.obj;
+ mInputMethodListListeners.forEach(
+ listener -> listener.onInputMethodListUpdated(imes, userId));
+ return true;
+ }
// ---------------------------------------------------------------
case MSG_INLINE_SUGGESTIONS_REQUEST:
@@ -4142,6 +4160,11 @@
// TODO: Make sure that mSwitchingController and mSettings are sharing the
// the same enabled IMEs list.
mSwitchingController.resetCircularListLocked(mContext);
+
+ // Notify InputMethodListListeners of the new installed InputMethods.
+ final List<InputMethodInfo> inputMethodList = new ArrayList<>(mMethodList);
+ mHandler.obtainMessage(MSG_DISPATCH_ON_INPUT_METHOD_LIST_UPDATED,
+ mSettings.getCurrentUserId(), 0 /* unused */, inputMethodList).sendToTarget();
}
// ----------------------------------------------------------------------
@@ -4606,6 +4629,11 @@
public boolean switchToInputMethod(String imeId, int userId) {
return mService.switchToInputMethod(imeId, userId);
}
+
+ @Override
+ public void registerInputMethodListListener(InputMethodListListener listener) {
+ mService.mInputMethodListListeners.addIfAbsent(listener);
+ }
}
@BinderThread
diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
index d09c478..54af694 100644
--- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
@@ -207,6 +207,12 @@
reportNotSupported();
return false;
}
+
+ @Override
+ public void registerInputMethodListListener(
+ InputMethodListListener listener) {
+ reportNotSupported();
+ }
});
}
diff --git a/services/core/java/com/android/server/location/AbstractLocationProvider.java b/services/core/java/com/android/server/location/AbstractLocationProvider.java
index 5afa48a..64bca78 100644
--- a/services/core/java/com/android/server/location/AbstractLocationProvider.java
+++ b/services/core/java/com/android/server/location/AbstractLocationProvider.java
@@ -21,6 +21,7 @@
import android.location.Location;
import android.os.Binder;
import android.os.Bundle;
+import android.util.ArraySet;
import com.android.internal.location.ProviderProperties;
import com.android.internal.location.ProviderRequest;
@@ -120,7 +121,8 @@
if (providerPackageNames.equals(this.providerPackageNames)) {
return this;
} else {
- return new State(allowed, properties, providerPackageNames);
+ return new State(allowed, properties,
+ Collections.unmodifiableSet(new ArraySet<>(providerPackageNames)));
}
}
diff --git a/services/core/java/com/android/server/location/AppForegroundHelper.java b/services/core/java/com/android/server/location/AppForegroundHelper.java
new file mode 100644
index 0000000..8ddfc65
--- /dev/null
+++ b/services/core/java/com/android/server/location/AppForegroundHelper.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.location;
+
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;
+import static android.app.ActivityManager.RunningAppProcessInfo.Importance;
+
+import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.content.Context;
+import android.os.Binder;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
+import com.android.server.FgThread;
+
+import java.util.Objects;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * Provides accessors and listeners for all application foreground status. An application is
+ * considered foreground if it's uid's importance level is at or more important than
+ * {@link android.app.ActivityManager.RunningAppProcessInfo#IMPORTANCE_FOREGROUND_SERVICE}.
+ */
+public class AppForegroundHelper {
+
+ /**
+ * Listener for application foreground state changes.
+ */
+ public interface AppForegroundListener {
+ /**
+ * Called when an application's foreground state changes.
+ */
+ void onAppForegroundChanged(int uid, boolean foreground);
+ }
+
+ // importance constants decrement with increasing importance - this is our limit for an
+ // importance level we consider foreground.
+ private static final int FOREGROUND_IMPORTANCE_CUTOFF = IMPORTANCE_FOREGROUND_SERVICE;
+
+ private static boolean isForeground(@Importance int importance) {
+ return importance <= FOREGROUND_IMPORTANCE_CUTOFF;
+ }
+
+ private final Context mContext;
+ private final CopyOnWriteArrayList<AppForegroundListener> mListeners;
+
+ @GuardedBy("this")
+ @Nullable private ActivityManager mActivityManager;
+
+ public AppForegroundHelper(Context context) {
+ mContext = context;
+ mListeners = new CopyOnWriteArrayList<>();
+ }
+
+ /** Called when system is ready. */
+ public synchronized void onSystemReady() {
+ if (mActivityManager != null) {
+ return;
+ }
+
+ mActivityManager = Objects.requireNonNull(mContext.getSystemService(ActivityManager.class));
+ mActivityManager.addOnUidImportanceListener(this::onAppForegroundChanged,
+ FOREGROUND_IMPORTANCE_CUTOFF);
+ }
+
+ /**
+ * Adds a listener for app foreground changed events. Callbacks occur on an unspecified thread.
+ */
+ public void addListener(AppForegroundListener listener) {
+ mListeners.add(listener);
+ }
+
+ /**
+ * Removes a listener for app foreground changed events.
+ */
+ public void removeListener(AppForegroundListener listener) {
+ mListeners.remove(listener);
+ }
+
+ private void onAppForegroundChanged(int uid, @Importance int importance) {
+ // invoked on ui thread, move to fg thread so we don't block the ui thread
+ boolean foreground = isForeground(importance);
+ FgThread.getHandler().post(() -> {
+ for (AppForegroundListener listener : mListeners) {
+ listener.onAppForegroundChanged(uid, foreground);
+ }
+ });
+ }
+
+ /**
+ * Whether the given uid is currently foreground.
+ */
+ public boolean isAppForeground(int uid) {
+ return isForeground(getImportance(uid));
+ }
+
+ /**
+ * Retrieves the current importance of the given uid.
+ *
+ * @deprecated Prefer {@link #isAppForeground(int)}.
+ */
+ @Deprecated
+ @Importance
+ public int getImportance(int uid) {
+ synchronized (this) {
+ Preconditions.checkState(mActivityManager != null);
+ }
+
+ long identity = Binder.clearCallingIdentity();
+ try {
+ return mActivityManager.getUidImportance(uid);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/location/GeofenceManager.java b/services/core/java/com/android/server/location/GeofenceManager.java
index 81c06d7..4e9c067 100644
--- a/services/core/java/com/android/server/location/GeofenceManager.java
+++ b/services/core/java/com/android/server/location/GeofenceManager.java
@@ -77,7 +77,7 @@
private final AppOpsManager mAppOps;
private final PowerManager.WakeLock mWakeLock;
- private final LocationSettingsStore mSettingsStore;
+ private final SettingsHelper mSettingsStore;
private final Object mLock = new Object();
@@ -111,7 +111,7 @@
*/
private boolean mPendingUpdate;
- public GeofenceManager(Context context, LocationSettingsStore settingsStore) {
+ public GeofenceManager(Context context, SettingsHelper settingsStore) {
mContext = context;
mHandler = new GeofenceHandler(FgThread.getHandler().getLooper());
diff --git a/services/core/java/com/android/server/location/GnssConfiguration.java b/services/core/java/com/android/server/location/GnssConfiguration.java
index 86a84e3..b3546dc 100644
--- a/services/core/java/com/android/server/location/GnssConfiguration.java
+++ b/services/core/java/com/android/server/location/GnssConfiguration.java
@@ -23,7 +23,8 @@
import android.telephony.SubscriptionManager;
import android.text.TextUtils;
import android.util.Log;
-import android.util.StatsLog;
+
+import com.android.internal.util.FrameworkStatsLog;
import libcore.io.IoUtils;
@@ -283,7 +284,7 @@
}
private void logConfigurations() {
- StatsLog.write(StatsLog.GNSS_CONFIGURATION_REPORTED,
+ FrameworkStatsLog.write(FrameworkStatsLog.GNSS_CONFIGURATION_REPORTED,
getSuplHost(),
getSuplPort(0),
getC2KHost(),
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 306e1e3..a7fd57a 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -43,7 +43,6 @@
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
-import android.os.HandlerExecutor;
import android.os.Looper;
import android.os.Message;
import android.os.PersistableBundle;
@@ -64,7 +63,6 @@
import android.telephony.gsm.GsmCellLocation;
import android.text.TextUtils;
import android.util.Log;
-import android.util.StatsLog;
import android.util.TimeUtils;
import com.android.internal.annotations.GuardedBy;
@@ -75,7 +73,9 @@
import com.android.internal.location.ProviderProperties;
import com.android.internal.location.ProviderRequest;
import com.android.internal.location.gnssmetrics.GnssMetrics;
+import com.android.internal.util.FrameworkStatsLog;
import com.android.server.DeviceIdleInternal;
+import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.location.GnssSatelliteBlacklistHelper.GnssSatelliteBlacklistCallback;
import com.android.server.location.NtpTimeHelper.InjectNtpTimeCallback;
@@ -624,12 +624,12 @@
}
}
- public GnssLocationProvider(Context context, Handler handler) {
- super(context, new HandlerExecutor(handler));
+ public GnssLocationProvider(Context context) {
+ super(context, FgThread.getExecutor());
ensureInitialized();
- mLooper = handler.getLooper();
+ mLooper = FgThread.getHandler().getLooper();
// Create a wake lock
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
@@ -1825,8 +1825,8 @@
}
native_send_ni_response(notificationId, userResponse);
- StatsLog.write(StatsLog.GNSS_NI_EVENT_REPORTED,
- StatsLog.GNSS_NI_EVENT_REPORTED__EVENT_TYPE__NI_RESPONSE,
+ FrameworkStatsLog.write(FrameworkStatsLog.GNSS_NI_EVENT_REPORTED,
+ FrameworkStatsLog.GNSS_NI_EVENT_REPORTED__EVENT_TYPE__NI_RESPONSE,
notificationId,
/* niType= */ 0,
/* needNotify= */ false,
@@ -1891,8 +1891,8 @@
notification.textEncoding = textEncoding;
mNIHandler.handleNiNotification(notification);
- StatsLog.write(StatsLog.GNSS_NI_EVENT_REPORTED,
- StatsLog.GNSS_NI_EVENT_REPORTED__EVENT_TYPE__NI_REQUEST,
+ FrameworkStatsLog.write(FrameworkStatsLog.GNSS_NI_EVENT_REPORTED,
+ FrameworkStatsLog.GNSS_NI_EVENT_REPORTED__EVENT_TYPE__NI_REQUEST,
notification.notificationId,
notification.niType,
notification.needNotify,
diff --git a/services/core/java/com/android/server/location/GnssVisibilityControl.java b/services/core/java/com/android/server/location/GnssVisibilityControl.java
index dd522b9..2b5fc79 100644
--- a/services/core/java/com/android/server/location/GnssVisibilityControl.java
+++ b/services/core/java/com/android/server/location/GnssVisibilityControl.java
@@ -36,11 +36,11 @@
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
-import android.util.StatsLog;
import com.android.internal.R;
import com.android.internal.location.GpsNetInitiatedHandler;
import com.android.internal.notification.SystemNotificationChannels;
+import com.android.internal.util.FrameworkStatsLog;
import java.util.Arrays;
import java.util.List;
@@ -650,7 +650,7 @@
}
private void logEvent(NfwNotification notification, boolean isPermissionMismatched) {
- StatsLog.write(StatsLog.GNSS_NFW_NOTIFICATION_REPORTED,
+ FrameworkStatsLog.write(FrameworkStatsLog.GNSS_NFW_NOTIFICATION_REPORTED,
notification.mProxyAppPackageName,
notification.mProtocolStack,
notification.mOtherProtocolStackName,
diff --git a/services/core/java/com/android/server/location/LocationUsageLogger.java b/services/core/java/com/android/server/location/LocationUsageLogger.java
index 755438b..93e19df 100644
--- a/services/core/java/com/android/server/location/LocationUsageLogger.java
+++ b/services/core/java/com/android/server/location/LocationUsageLogger.java
@@ -24,9 +24,9 @@
import android.location.LocationRequest;
import android.stats.location.LocationStatsEnums;
import android.util.Log;
-import android.util.StatsLog;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.FrameworkStatsLog;
import java.time.Instant;
@@ -61,8 +61,8 @@
boolean isLocationRequestNull = locationRequest == null;
boolean isGeofenceNull = geofence == null;
- StatsLog.write(StatsLog.LOCATION_MANAGER_API_USAGE_REPORTED, usageType,
- apiInUse, packageName,
+ FrameworkStatsLog.write(FrameworkStatsLog.LOCATION_MANAGER_API_USAGE_REPORTED,
+ usageType, apiInUse, packageName,
isLocationRequestNull
? LocationStatsEnums.PROVIDER_UNKNOWN
: bucketizeProvider(locationRequest.getProvider()),
@@ -101,7 +101,8 @@
return;
}
- StatsLog.write(StatsLog.LOCATION_MANAGER_API_USAGE_REPORTED, usageType, apiInUse,
+ FrameworkStatsLog.write(FrameworkStatsLog.LOCATION_MANAGER_API_USAGE_REPORTED,
+ usageType, apiInUse,
/* package_name= */ null,
bucketizeProvider(providerName),
LocationStatsEnums.QUALITY_UNKNOWN,
diff --git a/services/core/java/com/android/server/location/LocationSettingsStore.java b/services/core/java/com/android/server/location/SettingsHelper.java
similarity index 88%
rename from services/core/java/com/android/server/location/LocationSettingsStore.java
rename to services/core/java/com/android/server/location/SettingsHelper.java
index 0e8720e..9163490 100644
--- a/services/core/java/com/android/server/location/LocationSettingsStore.java
+++ b/services/core/java/com/android/server/location/SettingsHelper.java
@@ -54,7 +54,7 @@
/**
* Provides accessors and listeners for all location related settings.
*/
-public class LocationSettingsStore {
+public class SettingsHelper {
/**
* Listener for user-specific settings changes.
@@ -99,7 +99,7 @@
private final StringSetCachedGlobalSetting mIgnoreSettingsPackageWhitelist;
// TODO: get rid of handler
- public LocationSettingsStore(Context context, Handler handler) {
+ public SettingsHelper(Context context, Handler handler) {
mContext = context;
mLocationMode = new IntegerSecureSetting(context, LOCATION_MODE, handler);
@@ -118,7 +118,7 @@
}
/** Called when system is ready. */
- public synchronized void onSystemReady() {
+ public void onSystemReady() {
mLocationMode.register();
mBackgroundThrottleIntervalMs.register();
mLocationPackageBlacklist.register();
@@ -135,7 +135,8 @@
}
/**
- * Add a listener for changes to the location enabled setting.
+ * Add a listener for changes to the location enabled setting. Callbacks occur on an unspecified
+ * thread.
*/
public void addOnLocationEnabledChangedListener(UserSettingChangedListener listener) {
mLocationMode.addListener(listener);
@@ -156,7 +157,8 @@
}
/**
- * Add a listener for changes to the background throttle interval.
+ * Add a listener for changes to the background throttle interval. Callbacks occur on an
+ * unspecified thread.
*/
public void addOnBackgroundThrottleIntervalChangedListener(
GlobalSettingChangedListener listener) {
@@ -204,7 +206,8 @@
}
/**
- * Add a listener for changes to the background throttle package whitelist.
+ * Add a listener for changes to the background throttle package whitelist. Callbacks occur on
+ * an unspecified thread.
*/
public void addOnBackgroundThrottlePackageWhitelistChangedListener(
GlobalSettingChangedListener listener) {
@@ -227,7 +230,8 @@
}
/**
- * Add a listener for changes to the ignore settings package whitelist.
+ * Add a listener for changes to the ignore settings package whitelist. Callbacks occur on an
+ * unspecified thread.
*/
public void addOnIgnoreSettingsPackageWhitelistChangedListener(
GlobalSettingChangedListener listener) {
@@ -340,6 +344,8 @@
private abstract static class ObservingSetting extends ContentObserver {
private final CopyOnWriteArrayList<UserSettingChangedListener> mListeners;
+
+ @GuardedBy("this")
private boolean mRegistered;
private ObservingSetting(Handler handler) {
@@ -347,11 +353,11 @@
mListeners = new CopyOnWriteArrayList<>();
}
- protected boolean isRegistered() {
+ protected synchronized boolean isRegistered() {
return mRegistered;
}
- protected void register(Context context, Uri uri) {
+ protected synchronized void register(Context context, Uri uri) {
if (mRegistered) {
return;
}
@@ -393,8 +399,13 @@
}
public int getValueForUser(int defaultValue, int userId) {
- return Settings.Secure.getIntForUser(mContext.getContentResolver(), mSettingName,
- defaultValue, userId);
+ long identity = Binder.clearCallingIdentity();
+ try {
+ return Settings.Secure.getIntForUser(mContext.getContentResolver(), mSettingName,
+ defaultValue, userId);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
}
@@ -417,7 +428,7 @@
mCachedUserId = UserHandle.USER_NULL;
}
- public synchronized void register() {
+ public void register() {
register(mContext, Settings.Secure.getUriFor(mSettingName));
}
@@ -426,12 +437,17 @@
List<String> value = mCachedValue;
if (userId != mCachedUserId) {
- String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(),
- mSettingName, userId);
- if (TextUtils.isEmpty(setting)) {
- value = Collections.emptyList();
- } else {
- value = Arrays.asList(setting.split(","));
+ long identity = Binder.clearCallingIdentity();
+ try {
+ String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(),
+ mSettingName, userId);
+ if (TextUtils.isEmpty(setting)) {
+ value = Collections.emptyList();
+ } else {
+ value = Arrays.asList(setting.split(","));
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
if (isRegistered()) {
@@ -473,8 +489,13 @@
}
public long getValue(long defaultValue) {
- return Settings.Global.getLong(mContext.getContentResolver(), mSettingName,
- defaultValue);
+ long identity = Binder.clearCallingIdentity();
+ try {
+ return Settings.Global.getLong(mContext.getContentResolver(), mSettingName,
+ defaultValue);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
}
@@ -499,18 +520,23 @@
mValid = false;
}
- public synchronized void register() {
+ public void register() {
register(mContext, Settings.Global.getUriFor(mSettingName));
}
public synchronized Set<String> getValue() {
ArraySet<String> value = mCachedValue;
if (!mValid) {
- value = new ArraySet<>(mBaseValuesSupplier.get());
- String setting = Settings.Global.getString(mContext.getContentResolver(),
- mSettingName);
- if (!TextUtils.isEmpty(setting)) {
- value.addAll(Arrays.asList(setting.split(",")));
+ long identity = Binder.clearCallingIdentity();
+ try {
+ value = new ArraySet<>(mBaseValuesSupplier.get());
+ String setting = Settings.Global.getString(mContext.getContentResolver(),
+ mSettingName);
+ if (!TextUtils.isEmpty(setting)) {
+ value.addAll(Arrays.asList(setting.split(",")));
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
if (isRegistered()) {
diff --git a/services/core/java/com/android/server/location/UserInfoStore.java b/services/core/java/com/android/server/location/UserInfoHelper.java
similarity index 70%
rename from services/core/java/com/android/server/location/UserInfoStore.java
rename to services/core/java/com/android/server/location/UserInfoHelper.java
index f282ed2..94f3a88 100644
--- a/services/core/java/com/android/server/location/UserInfoStore.java
+++ b/services/core/java/com/android/server/location/UserInfoHelper.java
@@ -42,7 +42,7 @@
/**
* Provides accessors and listeners for all user info.
*/
-public class UserInfoStore {
+public class UserInfoHelper {
/**
* Listener for current user changes.
@@ -58,20 +58,16 @@
private final CopyOnWriteArrayList<UserChangedListener> mListeners;
@GuardedBy("this")
- @Nullable
- private UserManager mUserManager;
+ @Nullable private UserManager mUserManager;
+
+ @UserIdInt private volatile int mCurrentUserId;
@GuardedBy("this")
- @UserIdInt
- private int mCurrentUserId;
-
- @GuardedBy("this")
- @UserIdInt
- private int mCachedParentUserId;
+ @UserIdInt private int mCachedParentUserId;
@GuardedBy("this")
private int[] mCachedProfileUserIds;
- public UserInfoStore(Context context) {
+ public UserInfoHelper(Context context) {
mContext = context;
mListeners = new CopyOnWriteArrayList<>();
@@ -120,7 +116,7 @@
}
/**
- * Adds a listener for user changed events.
+ * Adds a listener for user changed events. Callbacks occur on an unspecified thread.
*/
public void addListener(UserChangedListener listener) {
mListeners.add(listener);
@@ -134,16 +130,13 @@
}
private void onUserChanged(@UserIdInt int newUserId) {
- int oldUserId;
- synchronized (this) {
- if (newUserId == mCurrentUserId) {
- return;
- }
-
- oldUserId = mCurrentUserId;
- mCurrentUserId = newUserId;
+ if (newUserId == mCurrentUserId) {
+ return;
}
+ int oldUserId = mCurrentUserId;
+ mCurrentUserId = newUserId;
+
for (UserChangedListener listener : mListeners) {
listener.onUserChanged(oldUserId, newUserId);
}
@@ -161,7 +154,7 @@
* Returns the user id of the current user.
*/
@UserIdInt
- public synchronized int getCurrentUserId() {
+ public int getCurrentUserId() {
return mCurrentUserId;
}
@@ -169,9 +162,10 @@
* Returns true if the given user id is either the current user or a profile of the current
* user.
*/
- public synchronized boolean isCurrentUserOrProfile(@UserIdInt int userId) {
- return userId == mCurrentUserId || ArrayUtils.contains(
- getProfileUserIdsForParentUser(mCurrentUserId), userId);
+ public boolean isCurrentUserOrProfile(@UserIdInt int userId) {
+ int currentUserId = mCurrentUserId;
+ return userId == currentUserId || ArrayUtils.contains(
+ getProfileUserIdsForParentUser(currentUserId), userId);
}
/**
@@ -179,50 +173,44 @@
* is a parent or has no profiles.
*/
@UserIdInt
- public synchronized int getParentUserId(@UserIdInt int userId) {
- int parentUserId;
- if (userId == mCachedParentUserId || ArrayUtils.contains(mCachedProfileUserIds, userId)) {
- parentUserId = mCachedParentUserId;
- } else {
- Preconditions.checkState(mUserManager != null);
-
- long identity = Binder.clearCallingIdentity();
- try {
- UserInfo userInfo = mUserManager.getProfileParent(userId);
- if (userInfo != null) {
- parentUserId = userInfo.id;
- } else {
- // getProfileParent() returns null if the userId is already the parent...
- parentUserId = userId;
- }
-
- // force profiles into cache
- getProfileUserIdsForParentUser(parentUserId);
- } finally {
- Binder.restoreCallingIdentity(identity);
+ public int getParentUserId(@UserIdInt int userId) {
+ synchronized (this) {
+ if (userId == mCachedParentUserId || ArrayUtils.contains(mCachedProfileUserIds,
+ userId)) {
+ return mCachedParentUserId;
}
+
+ Preconditions.checkState(mUserManager != null);
}
+ int parentUserId;
+
+ long identity = Binder.clearCallingIdentity();
+ try {
+ UserInfo userInfo = mUserManager.getProfileParent(userId);
+ parentUserId = userInfo != null ? userInfo.id : userId;
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+
+ // force profiles into cache
+ getProfileUserIdsForParentUser(parentUserId);
return parentUserId;
}
@GuardedBy("this")
- private int[] getProfileUserIdsForParentUser(@UserIdInt int parentUserId) {
- Preconditions.checkState(mUserManager != null);
-
- // only assert on debug builds as this is a more expensive check
- if (Build.IS_DEBUGGABLE) {
- long identity = Binder.clearCallingIdentity();
- try {
- Preconditions.checkArgument(mUserManager.getProfileParent(parentUserId) == null);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
-
+ private synchronized int[] getProfileUserIdsForParentUser(@UserIdInt int parentUserId) {
if (parentUserId != mCachedParentUserId) {
long identity = Binder.clearCallingIdentity();
try {
+ Preconditions.checkState(mUserManager != null);
+
+ // more expensive check - check that argument really is a parent user id
+ if (Build.IS_DEBUGGABLE) {
+ Preconditions.checkArgument(
+ mUserManager.getProfileParent(parentUserId) == null);
+ }
+
mCachedParentUserId = parentUserId;
mCachedProfileUserIds = mUserManager.getProfileIdsWithDisabled(parentUserId);
} finally {
@@ -236,8 +224,9 @@
/**
* Dump info for debugging.
*/
- public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("Current User: " + mCurrentUserId + " " + Arrays.toString(
- getProfileUserIdsForParentUser(mCurrentUserId)));
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ int currentUserId = mCurrentUserId;
+ pw.println("Current User: " + currentUserId + " " + Arrays.toString(
+ getProfileUserIdsForParentUser(currentUserId)));
}
}
diff --git a/services/core/java/com/android/server/location/gnss/GnssManagerService.java b/services/core/java/com/android/server/location/gnss/GnssManagerService.java
index 1eb2c52..2bab9fa 100644
--- a/services/core/java/com/android/server/location/gnss/GnssManagerService.java
+++ b/services/core/java/com/android/server/location/gnss/GnssManagerService.java
@@ -16,10 +16,11 @@
package com.android.server.location.gnss;
+import static android.app.AppOpsManager.OP_FINE_LOCATION;
+
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.content.Context;
import android.location.GnssCapabilities;
@@ -31,8 +32,8 @@
import android.location.IGpsGeofenceHardware;
import android.location.INetInitiatedListener;
import android.location.Location;
+import android.location.LocationManagerInternal;
import android.os.Binder;
-import android.os.Handler;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Process;
@@ -43,13 +44,12 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
-import com.android.server.FgThread;
-import com.android.server.LocationManagerService;
-import com.android.server.LocationManagerServiceUtils;
+import com.android.internal.util.Preconditions;
+import com.android.server.LocalServices;
import com.android.server.LocationManagerServiceUtils.LinkedListener;
import com.android.server.LocationManagerServiceUtils.LinkedListenerBase;
+import com.android.server.location.AppForegroundHelper;
import com.android.server.location.CallerIdentity;
import com.android.server.location.GnssBatchingProvider;
import com.android.server.location.GnssCapabilitiesProvider;
@@ -60,6 +60,7 @@
import com.android.server.location.GnssStatusListenerHelper;
import com.android.server.location.LocationUsageLogger;
import com.android.server.location.RemoteListenerHelper;
+import com.android.server.location.SettingsHelper;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -70,10 +71,18 @@
/** Manages Gnss providers and related Gnss functions for LocationManagerService. */
public class GnssManagerService {
- private static final String TAG = "GnssManagerService";
- private static final boolean D = Log.isLoggable(TAG, Log.DEBUG);
- // Providers
+ private static final String TAG = "GnssManagerService";
+
+ public static boolean isGnssSupported() {
+ return GnssLocationProvider.isSupported();
+ }
+
+ private final Context mContext;
+ private final SettingsHelper mSettingsHelper;
+ private final AppForegroundHelper mAppForegroundHelper;
+ private final LocationUsageLogger mLocationUsageLogger;
+
private final GnssLocationProvider mGnssLocationProvider;
private final GnssStatusListenerHelper mGnssStatusProvider;
private final GnssMeasurementsProvider mGnssMeasurementsProvider;
@@ -83,58 +92,59 @@
private final GnssLocationProvider.GnssMetricsProvider mGnssMetricsProvider;
private final GnssCapabilitiesProvider mGnssCapabilitiesProvider;
private final GnssBatchingProvider mGnssBatchingProvider;
-
private final INetInitiatedListener mNetInitiatedListener;
private final IGpsGeofenceHardware mGpsGeofenceProxy;
- private final LocationManagerService mLocationManagerService;
- private final LocationUsageLogger mLocationUsageLogger;
@GuardedBy("mGnssMeasurementsListeners")
- private final ArrayMap<IBinder,
- LinkedListener<IGnssMeasurementsListener>>
+ private final ArrayMap<IBinder, LinkedListener<IGnssMeasurementsListener>>
mGnssMeasurementsListeners = new ArrayMap<>();
@GuardedBy("mGnssNavigationMessageListeners")
- private final ArrayMap<
- IBinder, LinkedListener<IGnssNavigationMessageListener>>
+ private final ArrayMap<IBinder, LinkedListener<IGnssNavigationMessageListener>>
mGnssNavigationMessageListeners = new ArrayMap<>();
@GuardedBy("mGnssStatusListeners")
private final ArrayMap<IBinder, LinkedListener<IGnssStatusListener>>
mGnssStatusListeners = new ArrayMap<>();
- @GuardedBy("mGnssBatchingLock")
- private IBatchedLocationCallback mGnssBatchingCallback;
+ @GuardedBy("this")
+ @Nullable private LocationManagerInternal mLocationManagerInternal;
+ @GuardedBy("this")
+ @Nullable private AppOpsManager mAppOpsManager;
+
+ private final Object mGnssBatchingLock = new Object();
@GuardedBy("mGnssBatchingLock")
- private LinkedListener<IBatchedLocationCallback>
- mGnssBatchingDeathCallback;
+ @Nullable private IBatchedLocationCallback mGnssBatchingCallback;
+
+ @GuardedBy("mGnssBatchingLock")
+ @Nullable private LinkedListener<IBatchedLocationCallback> mGnssBatchingDeathCallback;
@GuardedBy("mGnssBatchingLock")
private boolean mGnssBatchingInProgress = false;
- private final Object mGnssBatchingLock = new Object();
- private final Context mContext;
- private final Handler mHandler;
-
- public GnssManagerService(LocationManagerService locationManagerService,
- Context context, LocationUsageLogger locationUsageLogger) {
- this(locationManagerService, context,
- new GnssLocationProvider(context, FgThread.getHandler()), locationUsageLogger);
+ public GnssManagerService(Context context, SettingsHelper settingsHelper,
+ AppForegroundHelper appForegroundHelper, LocationUsageLogger locationUsageLogger) {
+ this(context, settingsHelper, appForegroundHelper, locationUsageLogger, null);
}
// Can use this constructor to inject GnssLocationProvider for testing
@VisibleForTesting
- public GnssManagerService(LocationManagerService locationManagerService,
- Context context,
- GnssLocationProvider gnssLocationProvider,
- LocationUsageLogger locationUsageLogger) {
+ GnssManagerService(Context context, SettingsHelper settingsHelper,
+ AppForegroundHelper appForegroundHelper, LocationUsageLogger locationUsageLogger,
+ GnssLocationProvider gnssLocationProvider) {
+ Preconditions.checkState(isGnssSupported());
+
mContext = context;
- mHandler = FgThread.getHandler();
+ mSettingsHelper = settingsHelper;
+ mAppForegroundHelper = appForegroundHelper;
+ mLocationUsageLogger = locationUsageLogger;
- mGnssLocationProvider =
- gnssLocationProvider;
+ if (gnssLocationProvider == null) {
+ gnssLocationProvider = new GnssLocationProvider(mContext);
+ }
+ mGnssLocationProvider = gnssLocationProvider;
mGnssStatusProvider = mGnssLocationProvider.getGnssStatusProvider();
mGnssMeasurementsProvider = mGnssLocationProvider.getGnssMeasurementsProvider();
mGnssMeasurementCorrectionsProvider =
@@ -144,108 +154,73 @@
mGnssMetricsProvider = mGnssLocationProvider.getGnssMetricsProvider();
mGnssCapabilitiesProvider = mGnssLocationProvider.getGnssCapabilitiesProvider();
mGnssBatchingProvider = mGnssLocationProvider.getGnssBatchingProvider();
-
mNetInitiatedListener = mGnssLocationProvider.getNetInitiatedListener();
mGpsGeofenceProxy = mGnssLocationProvider.getGpsGeofenceProxy();
- mLocationManagerService = locationManagerService;
- mLocationUsageLogger = locationUsageLogger;
-
- registerUidListener();
}
- public static boolean isGnssSupported() {
- return GnssLocationProvider.isSupported();
- }
-
- private boolean hasGnssPermissions(String packageName) {
- mContext.enforceCallingPermission(
- Manifest.permission.ACCESS_FINE_LOCATION,
- "Fine location permission not granted.");
-
- int uid = Binder.getCallingUid();
- long identity = Binder.clearCallingIdentity();
- try {
- return mContext.getSystemService(
- AppOpsManager.class).checkOp(AppOpsManager.OP_FINE_LOCATION, uid, packageName)
- == AppOpsManager.MODE_ALLOWED;
- } finally {
- Binder.restoreCallingIdentity(identity);
+ /** Called when system is ready. */
+ public synchronized void onSystemReady() {
+ if (mLocationManagerInternal != null) {
+ return;
}
+
+ mSettingsHelper.onSystemReady();
+ mAppForegroundHelper.onSystemReady();
+
+ mLocationManagerInternal = LocalServices.getService(LocationManagerInternal.class);
+ mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
+
+ mAppForegroundHelper.addListener(this::onAppForegroundChanged);
}
+ /** Retrieve the GnssLocationProvider. */
public GnssLocationProvider getGnssLocationProvider() {
return mGnssLocationProvider;
}
+ /** Retrieve the IGpsGeofenceHardware. */
public IGpsGeofenceHardware getGpsGeofenceProxy() {
return mGpsGeofenceProxy;
}
/**
* Get year of GNSS hardware.
- *
- * @return year of GNSS hardware as an int if possible, otherwise zero
*/
public int getGnssYearOfHardware() {
- if (mGnssSystemInfoProvider != null) {
- return mGnssSystemInfoProvider.getGnssYearOfHardware();
- } else {
- return 0;
- }
+ return mGnssSystemInfoProvider.getGnssYearOfHardware();
}
/**
* Get model name of GNSS hardware.
- *
- * @return GNSS hardware model name as a string if possible, otherwise null
*/
+ @Nullable
public String getGnssHardwareModelName() {
- if (mGnssSystemInfoProvider != null) {
- return mGnssSystemInfoProvider.getGnssHardwareModelName();
- } else {
- return null;
- }
+ return mGnssSystemInfoProvider.getGnssHardwareModelName();
}
/**
- * Get GNSS hardware capabilities. The capabilities are described in {@link
- * android.location.GnssCapabilities} and their integer values correspond to the
- * bit positions in the returned {@code long} value.
- *
- * @param packageName name of requesting package
- * @return capabilities supported by the GNSS chipset
+ * Get GNSS hardware capabilities. The capabilities returned are a bitfield as described in
+ * {@link android.location.GnssCapabilities}.
*/
public long getGnssCapabilities(String packageName) {
- mContext.enforceCallingPermission(
- android.Manifest.permission.LOCATION_HARDWARE,
- "Location Hardware permission not granted to obtain GNSS chipset capabilities.");
- if (!hasGnssPermissions(packageName) || mGnssCapabilitiesProvider == null) {
+ mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE, null);
+ mContext.enforceCallingPermission(Manifest.permission.ACCESS_FINE_LOCATION, null);
+
+ if (!checkLocationAppOp(packageName)) {
return GnssCapabilities.INVALID_CAPABILITIES;
}
+
return mGnssCapabilitiesProvider.getGnssCapabilities();
}
/**
* Get size of GNSS batch (GNSS location results are batched together for power savings).
- * Requires LOCATION_HARDWARE and GNSS permissions.
- *
- * @param packageName name of requesting package
- * @return size of the GNSS batch collection
*/
public int getGnssBatchSize(String packageName) {
- mContext.enforceCallingPermission(
- android.Manifest.permission.LOCATION_HARDWARE,
- "Location Hardware permission not granted to access hardware batching");
+ mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE, null);
+ mContext.enforceCallingPermission(Manifest.permission.ACCESS_FINE_LOCATION, null);
- if (!hasGnssPermissions(packageName)) {
- Log.e(TAG, "getGnssBatchSize called without GNSS permissions");
- return 0;
- }
- if (mGnssBatchingProvider == null) {
- Log.e(
- TAG,
- "Can not get GNSS batch size. GNSS batching provider "
- + "not available.");
+ if (!checkLocationAppOp(packageName)) {
return 0;
}
@@ -257,27 +232,12 @@
/**
* Starts GNSS batch collection. GNSS positions are collected in a batch before being delivered
* as a collection.
- *
- * @param periodNanos duration over which to collect GPS positions before delivering as a
- * batch
- * @param wakeOnFifoFull specifying whether to wake on full queue
- * @param packageName name of requesting package
- * @return true of batch started successfully, false otherwise
*/
public boolean startGnssBatch(long periodNanos, boolean wakeOnFifoFull, String packageName) {
- mContext.enforceCallingPermission(
- android.Manifest.permission.LOCATION_HARDWARE,
- "Location Hardware permission not granted to access hardware batching");
+ mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE, null);
+ mContext.enforceCallingPermission(Manifest.permission.ACCESS_FINE_LOCATION, null);
- if (!hasGnssPermissions(packageName)) {
- Log.e(TAG, "startGnssBatch called without GNSS permissions");
- return false;
- }
- if (mGnssBatchingProvider == null) {
- Log.e(
- TAG,
- "Can not start GNSS batching. GNSS batching provider "
- + "not available.");
+ if (!checkLocationAppOp(packageName)) {
return false;
}
@@ -285,7 +245,6 @@
if (mGnssBatchingInProgress) {
// Current design does not expect multiple starts to be called repeatedly
Log.e(TAG, "startGnssBatch unexpectedly called w/o stopping prior batch");
- // Try to clean up anyway, and continue
stopGnssBatch();
}
@@ -296,26 +255,13 @@
/**
* Adds a GNSS batching callback for delivering GNSS location batch results.
- *
- * @param callback called when batching operation is complete to deliver GPS positions
- * @param packageName name of requesting package
- * @return true if callback is successfully added, false otherwise
*/
public boolean addGnssBatchingCallback(IBatchedLocationCallback callback, String packageName,
@Nullable String featureId, @NonNull String listenerIdentity) {
- mContext.enforceCallingPermission(
- android.Manifest.permission.LOCATION_HARDWARE,
- "Location Hardware permission not granted to access hardware batching");
+ mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE, null);
+ mContext.enforceCallingPermission(Manifest.permission.ACCESS_FINE_LOCATION, null);
- if (!hasGnssPermissions(packageName)) {
- Log.e(TAG, "addGnssBatchingCallback called without GNSS permissions");
- return false;
- }
- if (mGnssBatchingProvider == null) {
- Log.e(
- TAG,
- "Can not add GNSS batching callback. GNSS batching provider "
- + "not available.");
+ if (!checkLocationAppOp(packageName)) {
return false;
}
@@ -333,11 +279,9 @@
stopGnssBatch();
removeGnssBatchingCallback();
});
- if (!mGnssBatchingDeathCallback.linkToListenerDeathNotificationLocked(
- callback.asBinder())) {
- return false;
- }
- return true;
+
+ return mGnssBatchingDeathCallback.linkToListenerDeathNotificationLocked(
+ callback.asBinder());
}
}
@@ -347,27 +291,14 @@
* @param packageName name of requesting package
*/
public void flushGnssBatch(String packageName) {
- mContext.enforceCallingPermission(
- android.Manifest.permission.LOCATION_HARDWARE,
- "Location Hardware permission not granted to access hardware batching");
+ mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE, null);
+ mContext.enforceCallingPermission(Manifest.permission.ACCESS_FINE_LOCATION, null);
- if (!hasGnssPermissions(packageName)) {
- Log.e(TAG, "flushGnssBatch called without GNSS permissions");
- return;
- }
-
- if (mGnssBatchingProvider == null) {
- Log.e(
- TAG,
- "Can not flush GNSS batch. GNSS batching provider "
- + "not available.");
+ if (!checkLocationAppOp(packageName)) {
return;
}
synchronized (mGnssBatchingLock) {
- if (!mGnssBatchingInProgress) {
- Log.w(TAG, "flushGnssBatch called with no batch in progress");
- }
mGnssBatchingProvider.flush();
}
}
@@ -376,17 +307,7 @@
* Removes GNSS batching callback.
*/
public void removeGnssBatchingCallback() {
- mContext.enforceCallingPermission(
- android.Manifest.permission.LOCATION_HARDWARE,
- "Location Hardware permission not granted to access hardware batching");
-
- if (mGnssBatchingProvider == null) {
- Log.e(
- TAG,
- "Can not add GNSS batching callback. GNSS batching provider "
- + "not available.");
- return;
- }
+ mContext.enforceCallingPermission(android.Manifest.permission.LOCATION_HARDWARE, null);
synchronized (mGnssBatchingLock) {
mGnssBatchingDeathCallback.unlinkFromListenerDeathNotificationLocked(
@@ -398,44 +319,17 @@
/**
* Stop GNSS batch collection.
- *
- * @return true if GNSS batch successfully stopped, false otherwise
*/
public boolean stopGnssBatch() {
- mContext.enforceCallingPermission(
- android.Manifest.permission.LOCATION_HARDWARE,
- "Location Hardware permission not granted to access hardware batching");
+ mContext.enforceCallingPermission(android.Manifest.permission.LOCATION_HARDWARE, null);
- if (mGnssBatchingProvider == null) {
- Log.e(
- TAG,
- "Can not stop GNSS batch. GNSS batching provider "
- + "not available.");
- return false;
- }
synchronized (mGnssBatchingLock) {
mGnssBatchingInProgress = false;
return mGnssBatchingProvider.stop();
}
}
- private void registerUidListener() {
- mContext.getSystemService(
- ActivityManager.class).addOnUidImportanceListener(
- (uid, importance) -> {
- // listener invoked on ui thread, move to our thread to reduce risk
- // of blocking ui thread
- mHandler.post(
- () -> {
- onForegroundChanged(uid,
- LocationManagerServiceUtils.isImportanceForeground(
- importance));
- });
- },
- ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE);
- }
-
- private void onForegroundChanged(int uid, boolean foreground) {
+ private void onAppForegroundChanged(int uid, boolean foreground) {
synchronized (mGnssMeasurementsListeners) {
updateListenersOnForegroundChangedLocked(
mGnssMeasurementsListeners,
@@ -463,8 +357,7 @@
}
private <TListener extends IInterface> void updateListenersOnForegroundChangedLocked(
- ArrayMap<IBinder, ? extends LinkedListenerBase>
- gnssDataListeners,
+ Map<IBinder, ? extends LinkedListenerBase> gnssDataListeners,
RemoteListenerHelper<TListener> gnssDataProvider,
Function<IBinder, TListener> mapBinderToListener,
int uid,
@@ -477,18 +370,8 @@
continue;
}
- if (D) {
- Log.d(
- TAG,
- linkedListener.getListenerName()
- + " from uid "
- + uid
- + " is now "
- + LocationManagerServiceUtils.foregroundAsString(foreground));
- }
-
TListener listener = mapBinderToListener.apply(entry.getKey());
- if (foreground || mLocationManagerService.isThrottlingExemptLocked(callerIdentity)) {
+ if (foreground || isThrottlingExempt(callerIdentity)) {
gnssDataProvider.addListener(listener, callerIdentity);
} else {
gnssDataProvider.removeListener(listener);
@@ -502,67 +385,49 @@
@Nullable String featureId,
@NonNull String listenerIdentifier,
RemoteListenerHelper<TListener> gnssDataProvider,
- ArrayMap<IBinder,
- LinkedListener<TListener>> gnssDataListeners,
+ ArrayMap<IBinder, LinkedListener<TListener>> gnssDataListeners,
Consumer<TListener> binderDeathCallback) {
- if (!hasGnssPermissions(packageName)) {
- Log.e(TAG, "addGnssDataListenerLocked called without GNSS permissions");
+ mContext.enforceCallingPermission(Manifest.permission.ACCESS_FINE_LOCATION, null);
+
+ if (!checkLocationAppOp(packageName)) {
return false;
}
- if (gnssDataProvider == null) {
- Log.e(
- TAG,
- "Can not add GNSS data listener. GNSS data provider "
- + "not available.");
- return false;
- }
-
- CallerIdentity callerIdentity =
- new CallerIdentity(Binder.getCallingUid(), Binder.getCallingPid(), packageName,
- featureId, listenerIdentifier);
- LinkedListener<TListener> linkedListener =
- new LocationManagerServiceUtils.LinkedListener<>(
- listener, listenerIdentifier, callerIdentity, binderDeathCallback);
+ CallerIdentity callerIdentity = new CallerIdentity(Binder.getCallingUid(),
+ Binder.getCallingPid(), packageName, featureId, listenerIdentifier);
+ LinkedListener<TListener> linkedListener = new LinkedListener<>(listener,
+ listenerIdentifier, callerIdentity, binderDeathCallback);
IBinder binder = listener.asBinder();
if (!linkedListener.linkToListenerDeathNotificationLocked(binder)) {
return false;
}
gnssDataListeners.put(binder, linkedListener);
- long identity = Binder.clearCallingIdentity();
- try {
- if (gnssDataProvider == mGnssMeasurementsProvider
- || gnssDataProvider == mGnssStatusProvider) {
- mLocationUsageLogger.logLocationApiUsage(
- LocationStatsEnums.USAGE_STARTED,
- gnssDataProvider == mGnssMeasurementsProvider
- ? LocationStatsEnums.API_ADD_GNSS_MEASUREMENTS_LISTENER
- : LocationStatsEnums.API_REGISTER_GNSS_STATUS_CALLBACK,
- packageName,
- /* LocationRequest= */ null,
- /* hasListener= */ true,
- /* hasIntent= */ false,
- /* geofence= */ null,
- LocationManagerServiceUtils.getPackageImportance(packageName,
- mContext));
- }
- if (mLocationManagerService.isThrottlingExemptLocked(callerIdentity)
- || LocationManagerServiceUtils.isImportanceForeground(
- LocationManagerServiceUtils.getPackageImportance(packageName, mContext))) {
- gnssDataProvider.addListener(listener, callerIdentity);
- }
- return true;
- } finally {
- Binder.restoreCallingIdentity(identity);
+ if (gnssDataProvider == mGnssMeasurementsProvider
+ || gnssDataProvider == mGnssStatusProvider) {
+ mLocationUsageLogger.logLocationApiUsage(
+ LocationStatsEnums.USAGE_STARTED,
+ gnssDataProvider == mGnssMeasurementsProvider
+ ? LocationStatsEnums.API_ADD_GNSS_MEASUREMENTS_LISTENER
+ : LocationStatsEnums.API_REGISTER_GNSS_STATUS_CALLBACK,
+ packageName,
+ /* LocationRequest= */ null,
+ /* hasListener= */ true,
+ /* hasIntent= */ false,
+ /* geofence= */ null,
+ mAppForegroundHelper.getImportance(callerIdentity.mUid));
}
+ if (mAppForegroundHelper.isAppForeground(callerIdentity.mUid)
+ || isThrottlingExempt(callerIdentity)) {
+ gnssDataProvider.addListener(listener, callerIdentity);
+ }
+ return true;
}
- private <TListener extends IInterface> void removeGnssDataListener(
+ private <TListener extends IInterface> void removeGnssDataListenerLocked(
TListener listener,
RemoteListenerHelper<TListener> gnssDataProvider,
- ArrayMap<IBinder,
- LinkedListener<TListener>> gnssDataListeners) {
+ ArrayMap<IBinder, LinkedListener<TListener>> gnssDataListeners) {
if (gnssDataProvider == null) {
Log.e(
TAG,
@@ -577,25 +442,19 @@
if (linkedListener == null) {
return;
}
- long identity = Binder.clearCallingIdentity();
- try {
- if (gnssDataProvider == mGnssMeasurementsProvider
- || gnssDataProvider == mGnssStatusProvider) {
- mLocationUsageLogger.logLocationApiUsage(
- LocationStatsEnums.USAGE_ENDED,
- gnssDataProvider == mGnssMeasurementsProvider
- ? LocationStatsEnums.API_ADD_GNSS_MEASUREMENTS_LISTENER
- : LocationStatsEnums.API_REGISTER_GNSS_STATUS_CALLBACK,
- linkedListener.getCallerIdentity().mPackageName,
- /* LocationRequest= */ null,
- /* hasListener= */ true,
- /* hasIntent= */ false,
- /* geofence= */ null,
- LocationManagerServiceUtils.getPackageImportance(
- linkedListener.getCallerIdentity().mPackageName, mContext));
- }
- } finally {
- Binder.restoreCallingIdentity(identity);
+ if (gnssDataProvider == mGnssMeasurementsProvider
+ || gnssDataProvider == mGnssStatusProvider) {
+ mLocationUsageLogger.logLocationApiUsage(
+ LocationStatsEnums.USAGE_ENDED,
+ gnssDataProvider == mGnssMeasurementsProvider
+ ? LocationStatsEnums.API_ADD_GNSS_MEASUREMENTS_LISTENER
+ : LocationStatsEnums.API_REGISTER_GNSS_STATUS_CALLBACK,
+ linkedListener.getCallerIdentity().mPackageName,
+ /* LocationRequest= */ null,
+ /* hasListener= */ true,
+ /* hasIntent= */ false,
+ /* geofence= */ null,
+ mAppForegroundHelper.getImportance(Binder.getCallingUid()));
}
linkedListener.unlinkFromListenerDeathNotificationLocked(binder);
gnssDataProvider.removeListener(listener);
@@ -603,10 +462,6 @@
/**
* Registers listener for GNSS status changes.
- *
- * @param listener called when GNSS status changes
- * @param packageName name of requesting package
- * @return true if listener is successfully registered, false otherwise
*/
public boolean registerGnssStatusCallback(IGnssStatusListener listener, String packageName,
@Nullable String featureId) {
@@ -624,21 +479,15 @@
/**
* Unregisters listener for GNSS status changes.
- *
- * @param listener called when GNSS status changes
*/
public void unregisterGnssStatusCallback(IGnssStatusListener listener) {
synchronized (mGnssStatusListeners) {
- removeGnssDataListener(listener, mGnssStatusProvider, mGnssStatusListeners);
+ removeGnssDataListenerLocked(listener, mGnssStatusProvider, mGnssStatusListeners);
}
}
/**
* Adds a GNSS measurements listener.
- *
- * @param listener called when GNSS measurements are received
- * @param packageName name of requesting package
- * @return true if listener is successfully added, false otherwise
*/
public boolean addGnssMeasurementsListener(
IGnssMeasurementsListener listener, String packageName, @Nullable String featureId,
@@ -657,47 +506,32 @@
/**
* Injects GNSS measurement corrections.
- *
- * @param measurementCorrections GNSS measurement corrections
- * @param packageName name of requesting package
*/
public void injectGnssMeasurementCorrections(
GnssMeasurementCorrections measurementCorrections, String packageName) {
- mContext.enforceCallingPermission(
- android.Manifest.permission.LOCATION_HARDWARE,
- "Location Hardware permission not granted to inject GNSS measurement corrections.");
- if (!hasGnssPermissions(packageName)) {
- Log.e(TAG, "Can not inject GNSS corrections due to no permission.");
+ mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE, null);
+ mContext.enforceCallingPermission(Manifest.permission.ACCESS_FINE_LOCATION, null);
+
+ if (!checkLocationAppOp(packageName)) {
return;
}
- if (mGnssMeasurementCorrectionsProvider == null) {
- Log.e(
- TAG,
- "Can not inject GNSS corrections. GNSS measurement corrections provider "
- + "not available.");
- return;
- }
+
mGnssMeasurementCorrectionsProvider.injectGnssMeasurementCorrections(
measurementCorrections);
}
/**
* Removes a GNSS measurements listener.
- *
- * @param listener called when GNSS measurements are received
*/
public void removeGnssMeasurementsListener(IGnssMeasurementsListener listener) {
synchronized (mGnssMeasurementsListeners) {
- removeGnssDataListener(listener, mGnssMeasurementsProvider, mGnssMeasurementsListeners);
+ removeGnssDataListenerLocked(listener, mGnssMeasurementsProvider,
+ mGnssMeasurementsListeners);
}
}
/**
* Adds a GNSS navigation message listener.
- *
- * @param listener called when navigation message is received
- * @param packageName name of requesting package
- * @return true if listener is successfully added, false otherwise
*/
public boolean addGnssNavigationMessageListener(
IGnssNavigationMessageListener listener, String packageName,
@@ -716,12 +550,10 @@
/**
* Removes a GNSS navigation message listener.
- *
- * @param listener called when navigation message is received
*/
public void removeGnssNavigationMessageListener(IGnssNavigationMessageListener listener) {
synchronized (mGnssNavigationMessageListeners) {
- removeGnssDataListener(
+ removeGnssDataListenerLocked(
listener, mGnssNavigationMessageProvider, mGnssNavigationMessageListeners);
}
}
@@ -729,43 +561,62 @@
/**
* Send Ni Response, indicating a location request initiated by a network carrier.
*/
- public boolean sendNiResponse(int notifId, int userResponse) {
- if (Binder.getCallingUid() != Process.myUid()) {
- throw new SecurityException(
- "calling sendNiResponse from outside of the system is not allowed");
- }
+ public void sendNiResponse(int notifId, int userResponse) {
try {
- return mNetInitiatedListener.sendNiResponse(notifId, userResponse);
+ mNetInitiatedListener.sendNiResponse(notifId, userResponse);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException in LocationManagerService.sendNiResponse");
- return false;
}
}
/**
* Report location results to GNSS batching listener.
- *
- * @param locations batch of locations to report to GNSS batching callback
*/
public void onReportLocation(List<Location> locations) {
- if (mGnssBatchingCallback == null) {
- Log.e(TAG, "reportLocationBatch() called without active Callback");
+ IBatchedLocationCallback gnssBatchingCallback;
+ synchronized (mGnssBatchingLock) {
+ gnssBatchingCallback = mGnssBatchingCallback;
+ }
+
+ if (gnssBatchingCallback == null) {
return;
}
try {
- mGnssBatchingCallback.onLocationBatch(locations);
+ gnssBatchingCallback.onLocationBatch(locations);
} catch (RemoteException e) {
Log.e(TAG, "mGnssBatchingCallback.onLocationBatch failed", e);
}
}
+ private boolean isThrottlingExempt(CallerIdentity callerIdentity) {
+ if (callerIdentity.mUid == Process.SYSTEM_UID) {
+ return true;
+ }
+
+ if (mSettingsHelper.getBackgroundThrottlePackageWhitelist().contains(
+ callerIdentity.mPackageName)) {
+ return true;
+ }
+
+ synchronized (this) {
+ Preconditions.checkState(mLocationManagerInternal != null);
+ }
+ return mLocationManagerInternal.isProviderPackage(callerIdentity.mPackageName);
+ }
+
+ private boolean checkLocationAppOp(String packageName) {
+ synchronized (this) {
+ Preconditions.checkState(mAppOpsManager != null);
+ }
+ return mAppOpsManager.checkOp(OP_FINE_LOCATION, Binder.getCallingUid(), packageName)
+ == AppOpsManager.MODE_ALLOWED;
+ }
+
/**
- * Dump for debugging.
+ * Dump info for debugging.
*/
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
-
IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
if (args.length > 0 && args[0].equals("--gnssmetrics")) {
@@ -778,11 +629,8 @@
ipw.println("GnssMeasurement Listeners:");
ipw.increaseIndent();
synchronized (mGnssMeasurementsListeners) {
- for (LinkedListenerBase listener :
- mGnssMeasurementsListeners
- .values()) {
- ipw.println(listener + ": " + mLocationManagerService.isThrottlingExemptLocked(
- listener.getCallerIdentity()));
+ for (LinkedListenerBase listener : mGnssMeasurementsListeners.values()) {
+ ipw.println(listener);
}
}
ipw.decreaseIndent();
@@ -790,10 +638,8 @@
ipw.println("GnssNavigationMessage Listeners:");
ipw.increaseIndent();
synchronized (mGnssNavigationMessageListeners) {
- for (LinkedListenerBase listener :
- mGnssNavigationMessageListeners.values()) {
- ipw.println(listener + ": " + mLocationManagerService.isThrottlingExemptLocked(
- listener.getCallerIdentity()));
+ for (LinkedListenerBase listener : mGnssNavigationMessageListeners.values()) {
+ ipw.println(listener);
}
}
ipw.decreaseIndent();
@@ -801,10 +647,8 @@
ipw.println("GnssStatus Listeners:");
ipw.increaseIndent();
synchronized (mGnssStatusListeners) {
- for (LinkedListenerBase listener :
- mGnssStatusListeners.values()) {
- ipw.println(listener + ": " + mLocationManagerService.isThrottlingExemptLocked(
- listener.getCallerIdentity()));
+ for (LinkedListenerBase listener : mGnssStatusListeners.values()) {
+ ipw.println(listener);
}
}
ipw.decreaseIndent();
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java
index c6d2b33..90afeff 100644
--- a/services/core/java/com/android/server/pm/ApexManager.java
+++ b/services/core/java/com/android/server/pm/ApexManager.java
@@ -96,7 +96,7 @@
* depending on whether this device supports APEX, i.e. {@link ApexProperties#updatable()}
* evaluates to {@code true}.
*/
- static ApexManager getInstance() {
+ public static ApexManager getInstance() {
return sApexManagerSingleton.get();
}
@@ -272,6 +272,21 @@
public abstract String getApexModuleNameForPackageName(String apexPackageName);
/**
+ * Copies the CE apex data directory for the given {@code userId} to a backup location, for use
+ * in case of rollback.
+ *
+ * @return long inode for the snapshot directory if the snapshot was successful, or -1 if not
+ */
+ public abstract long snapshotCeData(int userId, int rollbackId, String apexPackageName);
+
+ /**
+ * Restores the snapshot of the CE apex data directory for the given {@code userId}.
+ *
+ * @return boolean true if the restore was successful
+ */
+ public abstract boolean restoreCeData(int userId, int rollbackId, String apexPackageName);
+
+ /**
* Dumps various state information to the provided {@link PrintWriter} object.
*
* @param pw the {@link PrintWriter} object to send information to.
@@ -662,6 +677,45 @@
}
}
+ @Override
+ public long snapshotCeData(int userId, int rollbackId, String apexPackageName) {
+ populatePackageNameToApexModuleNameIfNeeded();
+ String apexModuleName;
+ synchronized (mLock) {
+ apexModuleName = mPackageNameToApexModuleName.get(apexPackageName);
+ }
+ if (apexModuleName == null) {
+ Slog.e(TAG, "Invalid apex package name: " + apexPackageName);
+ return -1;
+ }
+ try {
+ return mApexService.snapshotCeData(userId, rollbackId, apexModuleName);
+ } catch (Exception e) {
+ Slog.e(TAG, e.getMessage(), e);
+ return -1;
+ }
+ }
+
+ @Override
+ public boolean restoreCeData(int userId, int rollbackId, String apexPackageName) {
+ populatePackageNameToApexModuleNameIfNeeded();
+ String apexModuleName;
+ synchronized (mLock) {
+ apexModuleName = mPackageNameToApexModuleName.get(apexPackageName);
+ }
+ if (apexModuleName == null) {
+ Slog.e(TAG, "Invalid apex package name: " + apexPackageName);
+ return false;
+ }
+ try {
+ mApexService.restoreCeData(userId, rollbackId, apexModuleName);
+ return true;
+ } catch (Exception e) {
+ Slog.e(TAG, e.getMessage(), e);
+ return false;
+ }
+ }
+
/**
* Dump information about the packages contained in a particular cache
* @param packagesCache the cache to print information about.
@@ -865,6 +919,16 @@
}
@Override
+ public long snapshotCeData(int userId, int rollbackId, String apexPackageName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean restoreCeData(int userId, int rollbackId, String apexPackageName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
void dump(PrintWriter pw, String packageName) {
// No-op
}
diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java
index 5c17bec..7f73bae 100644
--- a/services/core/java/com/android/server/pm/AppsFilter.java
+++ b/services/core/java/com/android/server/pm/AppsFilter.java
@@ -68,9 +68,8 @@
// Logs all filtering instead of enforcing
private static final boolean DEBUG_ALLOW_ALL = false;
-
- @SuppressWarnings("ConstantExpression")
- private static final boolean DEBUG_LOGGING = false | DEBUG_ALLOW_ALL;
+ private static final boolean DEBUG_LOGGING = false;
+ private static final boolean FEATURE_ENABLED_BY_DEFAULT = false;
/**
* This contains a list of app UIDs that are implicitly queryable because another app explicitly
@@ -136,7 +135,7 @@
private static class FeatureConfigImpl implements FeatureConfig {
private static final String FILTERING_ENABLED_NAME = "package_query_filtering_enabled";
private final PackageManagerService.Injector mInjector;
- private volatile boolean mFeatureEnabled = false;
+ private volatile boolean mFeatureEnabled = FEATURE_ENABLED_BY_DEFAULT;
private FeatureConfigImpl(PackageManagerService.Injector injector) {
mInjector = injector;
@@ -145,14 +144,15 @@
@Override
public void onSystemReady() {
mFeatureEnabled = DeviceConfig.getBoolean(
- NAMESPACE_PACKAGE_MANAGER_SERVICE, FILTERING_ENABLED_NAME, false);
+ NAMESPACE_PACKAGE_MANAGER_SERVICE, FILTERING_ENABLED_NAME,
+ FEATURE_ENABLED_BY_DEFAULT);
DeviceConfig.addOnPropertiesChangedListener(
NAMESPACE_PACKAGE_MANAGER_SERVICE, FgThread.getExecutor(),
properties -> {
if (properties.getKeyset().contains(FILTERING_ENABLED_NAME)) {
synchronized (FeatureConfigImpl.this) {
mFeatureEnabled = properties.getBoolean(FILTERING_ENABLED_NAME,
- false);
+ FEATURE_ENABLED_BY_DEFAULT);
}
}
});
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 43ed25f..431b4dc 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -154,10 +154,9 @@
private static final boolean LOGD = true;
private static final String REMOVE_MARKER_EXTENSION = ".removed";
- private static final int MSG_COMMIT = 1;
- private static final int MSG_ON_PACKAGE_INSTALLED = 2;
- private static final int MSG_SEAL = 3;
- private static final int MSG_STREAM_AND_VALIDATE = 4;
+ private static final int MSG_STREAM_VALIDATE_AND_COMMIT = 1;
+ private static final int MSG_INSTALL = 2;
+ private static final int MSG_ON_PACKAGE_INSTALLED = 3;
/** XML constants used for persisting a session */
static final String TAG_SESSION = "session";
@@ -415,14 +414,11 @@
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
- case MSG_SEAL:
- handleSeal((IntentSender) msg.obj);
+ case MSG_STREAM_VALIDATE_AND_COMMIT:
+ handleStreamValidateAndCommit();
break;
- case MSG_STREAM_AND_VALIDATE:
- handleStreamAndValidate();
- break;
- case MSG_COMMIT:
- handleCommit();
+ case MSG_INSTALL:
+ handleInstall();
break;
case MSG_ON_PACKAGE_INSTALLED:
final SomeArgs args = (SomeArgs) msg.obj;
@@ -1011,24 +1007,7 @@
+ mParentSessionId + " and may not be committed directly.");
}
- assertCanBeCommitted(forTransfer);
-
- if (isMultiPackage()) {
- for (int i = mChildSessionIds.size() - 1; i >= 0; --i) {
- final int childSessionId = mChildSessionIds.keyAt(i);
- mSessionProvider.getSession(childSessionId).assertCanBeCommitted(forTransfer);
- }
- }
-
- if (mIncrementalFileStorages != null) {
- mIncrementalFileStorages.finishSetUp();
- }
-
- mHandler.obtainMessage(MSG_SEAL, statusReceiver).sendToTarget();
- }
-
- private void handleSeal(@NonNull IntentSender statusReceiver) {
- if (!markAsSealed(statusReceiver)) {
+ if (!markAsSealed(statusReceiver, forTransfer)) {
return;
}
if (isMultiPackage()) {
@@ -1042,7 +1021,7 @@
// seal all children, regardless if any of them fail; we'll throw/return
// as appropriate once all children have been processed
if (!mSessionProvider.getSession(childSessionId)
- .markAsSealed(childIntentSender)) {
+ .markAsSealed(childIntentSender, forTransfer)) {
sealFailed = true;
}
}
@@ -1051,20 +1030,24 @@
}
}
- dispatchStreamAndValidate();
+ if (mIncrementalFileStorages != null) {
+ mIncrementalFileStorages.finishSetUp();
+ }
+
+ dispatchStreamValidateAndCommit();
}
- private void dispatchStreamAndValidate() {
- mHandler.obtainMessage(MSG_STREAM_AND_VALIDATE).sendToTarget();
+ private void dispatchStreamValidateAndCommit() {
+ mHandler.obtainMessage(MSG_STREAM_VALIDATE_AND_COMMIT).sendToTarget();
}
- private void handleStreamAndValidate() {
+ private void handleStreamValidateAndCommit() {
// TODO(b/136132412): update with new APIs
if (mIncrementalFileStorages != null) {
mIncrementalFileStorages.startLoading();
}
- boolean commitFailed = !markAsCommitted();
+ boolean success = streamValidateAndCommit();
if (isMultiPackage()) {
for (int i = mChildSessionIds.size() - 1; i >= 0; --i) {
@@ -1072,17 +1055,17 @@
// commit all children, regardless if any of them fail; we'll throw/return
// as appropriate once all children have been processed
if (!mSessionProvider.getSession(childSessionId)
- .markAsCommitted()) {
- commitFailed = true;
+ .streamValidateAndCommit()) {
+ success = false;
}
}
}
- if (commitFailed) {
+ if (!success) {
return;
}
- mHandler.obtainMessage(MSG_COMMIT).sendToTarget();
+ mHandler.obtainMessage(MSG_INSTALL).sendToTarget();
}
private final class FileSystemConnector extends
@@ -1201,9 +1184,16 @@
}
/**
- * Sanity checks to make sure it's ok to commit the session.
+ * If this was not already called, the session will be sealed.
+ *
+ * This method may be called multiple times to update the status receiver validate caller
+ * permissions.
*/
- private void assertCanBeCommitted(boolean forTransfer) {
+ private boolean markAsSealed(@NonNull IntentSender statusReceiver, boolean forTransfer) {
+ Objects.requireNonNull(statusReceiver);
+
+ List<PackageInstallerSession> childSessions = getChildSessions();
+
synchronized (mLock) {
assertCallerIsOwnerOrRootLocked();
assertPreparedAndNotDestroyedLocked("commit");
@@ -1226,21 +1216,7 @@
throw new IllegalArgumentException("Session has been transferred");
}
}
- }
- }
- /**
- * If this was not already called, the session will be sealed.
- *
- * This method may be called multiple times to update the status receiver validate caller
- * permissions.
- */
- private boolean markAsSealed(@NonNull IntentSender statusReceiver) {
- Objects.requireNonNull(statusReceiver);
-
- List<PackageInstallerSession> childSessions = getChildSessions();
-
- synchronized (mLock) {
mRemoteStatusReceiver = statusReceiver;
// After updating the observer, we can skip re-sealing.
@@ -1263,10 +1239,8 @@
return true;
}
- private boolean markAsCommitted() {
+ private boolean streamValidateAndCommit() {
synchronized (mLock) {
- Objects.requireNonNull(mRemoteStatusReceiver);
-
if (mCommitted) {
return true;
}
@@ -1519,7 +1493,7 @@
mCallback.onSessionSealedBlocking(this);
}
- private void handleCommit() {
+ private void handleInstall() {
if (isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked()) {
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.INSTALL_PACKAGE)
@@ -1548,7 +1522,7 @@
try {
synchronized (mLock) {
- commitNonStagedLocked(childSessions);
+ installNonStagedLocked(childSessions);
}
} catch (PackageManagerException e) {
final String completeMsg = ExceptionUtils.getCompleteMessage(e);
@@ -1559,25 +1533,25 @@
}
@GuardedBy("mLock")
- private void commitNonStagedLocked(List<PackageInstallerSession> childSessions)
+ private void installNonStagedLocked(List<PackageInstallerSession> childSessions)
throws PackageManagerException {
- final PackageManagerService.ActiveInstallSession committingSession =
+ final PackageManagerService.ActiveInstallSession installingSession =
makeSessionActiveLocked();
- if (committingSession == null) {
+ if (installingSession == null) {
return;
}
if (isMultiPackage()) {
- List<PackageManagerService.ActiveInstallSession> activeChildSessions =
+ List<PackageManagerService.ActiveInstallSession> installingChildSessions =
new ArrayList<>(childSessions.size());
boolean success = true;
PackageManagerException failure = null;
for (int i = 0; i < childSessions.size(); ++i) {
final PackageInstallerSession session = childSessions.get(i);
try {
- final PackageManagerService.ActiveInstallSession activeSession =
+ final PackageManagerService.ActiveInstallSession installingChildSession =
session.makeSessionActiveLocked();
- if (activeSession != null) {
- activeChildSessions.add(activeSession);
+ if (installingChildSession != null) {
+ installingChildSessions.add(installingChildSession);
}
} catch (PackageManagerException e) {
failure = e;
@@ -1591,9 +1565,9 @@
failure.error, failure.getLocalizedMessage(), null);
return;
}
- mPm.installStage(activeChildSessions);
+ mPm.installStage(installingChildSessions);
} else {
- mPm.installStage(committingSession);
+ mPm.installStage(installingSession);
}
}
@@ -2306,7 +2280,7 @@
// Mark and kick off another install pass
synchronized (mLock) {
mPermissionsManuallyAccepted = true;
- mHandler.obtainMessage(MSG_COMMIT).sendToTarget();
+ mHandler.obtainMessage(MSG_INSTALL).sendToTarget();
}
} else {
destroyInternal();
@@ -2536,9 +2510,9 @@
mDataLoaderFinished = true;
if (hasParentSessionId()) {
mSessionProvider.getSession(
- mParentSessionId).dispatchStreamAndValidate();
+ mParentSessionId).dispatchStreamValidateAndCommit();
} else {
- dispatchStreamAndValidate();
+ dispatchStreamValidateAndCommit();
}
dataLoader.destroy();
break;
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index ae28019..8935453 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -344,12 +344,12 @@
}
/**
+ * Perform snapshot and restore as required both for APEXes themselves and for apks in APEX.
* Apks inside apex are not installed using apk-install flow. They are scanned from the system
* directory directly by PackageManager, as such, RollbackManager need to handle their data
* separately here.
*/
- private void snapshotAndRestoreApkInApexUserData(PackageInstallerSession session) {
- // We want to process apks inside apex. So current session needs to contain apex.
+ private void snapshotAndRestoreForApexSession(PackageInstallerSession session) {
if (!sessionContainsApex(session)) {
return;
}
@@ -382,19 +382,37 @@
apexSessions.add(session);
}
- // For each apex, process the apks inside it
+ final UserManagerInternal um = LocalServices.getService(UserManagerInternal.class);
+ final int[] allUsers = um.getUserIds();
+ IRollbackManager rm = IRollbackManager.Stub.asInterface(
+ ServiceManager.getService(Context.ROLLBACK_SERVICE));
+
for (PackageInstallerSession apexSession : apexSessions) {
- List<String> apksInApex = mApexManager.getApksInApex(apexSession.getPackageName());
+ String packageName = apexSession.getPackageName();
+ // Perform any snapshots or restores for the APEX itself
+ snapshotAndRestoreApexUserData(packageName, allUsers, rm);
+
+ // Process the apks inside the APEX
+ List<String> apksInApex = mApexManager.getApksInApex(packageName);
for (String apk: apksInApex) {
- snapshotAndRestoreApkInApexUserData(apk);
+ snapshotAndRestoreApkInApexUserData(apk, allUsers, rm);
}
}
}
- private void snapshotAndRestoreApkInApexUserData(String packageName) {
- IRollbackManager rm = IRollbackManager.Stub.asInterface(
- ServiceManager.getService(Context.ROLLBACK_SERVICE));
+ private void snapshotAndRestoreApexUserData(
+ String packageName, int[] allUsers, IRollbackManager rm) {
+ try {
+ // appId, ceDataInode, and seInfo are not needed for APEXes
+ rm.snapshotAndRestoreUserData(packageName, allUsers, 0, 0,
+ null, 0 /*token*/);
+ } catch (RemoteException re) {
+ Slog.e(TAG, "Error snapshotting/restoring user data: " + re);
+ }
+ }
+ private void snapshotAndRestoreApkInApexUserData(
+ String packageName, int[] allUsers, IRollbackManager rm) {
PackageManagerInternal mPmi = LocalServices.getService(PackageManagerInternal.class);
AndroidPackage pkg = mPmi.getPackage(packageName);
if (pkg == null) {
@@ -403,13 +421,11 @@
return;
}
final String seInfo = pkg.getSeInfo();
- final UserManagerInternal um = LocalServices.getService(UserManagerInternal.class);
- final int[] allUsers = um.getUserIds();
int appId = -1;
long ceDataInode = -1;
final PackageSetting ps = (PackageSetting) mPmi.getPackageSetting(packageName);
- if (ps != null && rm != null) {
+ if (ps != null) {
appId = ps.appId;
ceDataInode = ps.getCeDataInode(UserHandle.USER_SYSTEM);
// NOTE: We ignore the user specified in the InstallParam because we know this is
@@ -498,7 +514,7 @@
abortCheckpoint();
return;
}
- snapshotAndRestoreApkInApexUserData(session);
+ snapshotAndRestoreForApexSession(session);
Slog.i(TAG, "APEX packages in session " + session.sessionId
+ " were successfully activated. Proceeding with APK packages, if any");
}
diff --git a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
index f3a6018..81ec466 100644
--- a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
+++ b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
@@ -18,12 +18,14 @@
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
+import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
import static android.app.AppOpsManager.OP_LEGACY_STORAGE;
import static android.app.AppOpsManager.OP_NONE;
import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static java.lang.Integer.min;
@@ -114,6 +116,7 @@
boolean shouldApplyRestriction;
final int targetSDK;
final boolean hasRequestedLegacyExternalStorage;
+ final boolean hasWriteMediaStorageGrantedForUid;
if (appInfo != null) {
PackageManager pm = context.getPackageManager();
@@ -123,11 +126,14 @@
targetSDK = getMinimumTargetSDK(context, appInfo, user);
hasRequestedLegacyExternalStorage = hasUidRequestedLegacyExternalStorage(
appInfo.uid, context);
+ hasWriteMediaStorageGrantedForUid = hasWriteMediaStorageGrantedForUid(
+ appInfo.uid, context);
} else {
isWhiteListed = false;
shouldApplyRestriction = false;
targetSDK = 0;
hasRequestedLegacyExternalStorage = false;
+ hasWriteMediaStorageGrantedForUid = false;
}
// We have a check in PermissionPolicyService.PermissionToOpSynchroniser.setUidMode
@@ -145,8 +151,9 @@
}
@Override
public boolean mayAllowExtraAppOp() {
- return !shouldApplyRestriction && hasRequestedLegacyExternalStorage
- && targetSDK <= Build.VERSION_CODES.Q;
+ return !shouldApplyRestriction && targetSDK <= Build.VERSION_CODES.Q
+ && (hasRequestedLegacyExternalStorage
+ || hasWriteMediaStorageGrantedForUid);
}
@Override
public boolean mayDenyExtraAppOpIfGranted() {
@@ -201,6 +208,22 @@
return false;
}
+ private static boolean hasWriteMediaStorageGrantedForUid(int uid, @NonNull Context context) {
+ PackageManager packageManager = context.getPackageManager();
+ String[] packageNames = packageManager.getPackagesForUid(uid);
+ if (packageNames == null) {
+ return false;
+ }
+
+ for (String packageName : packageNames) {
+ if (packageManager.checkPermission(WRITE_MEDIA_STORAGE, packageName)
+ == PERMISSION_GRANTED) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* @return If the permission can be granted
*/
diff --git a/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java b/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
index e6e6e23..e77839c 100644
--- a/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
+++ b/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
@@ -26,6 +26,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.pm.ApexManager;
import com.android.server.pm.Installer;
import com.android.server.pm.Installer.InstallerException;
@@ -42,9 +43,17 @@
private static final String TAG = "RollbackManager";
private final Installer mInstaller;
+ private final ApexManager mApexManager;
public AppDataRollbackHelper(Installer installer) {
mInstaller = installer;
+ mApexManager = ApexManager.getInstance();
+ }
+
+ @VisibleForTesting
+ AppDataRollbackHelper(Installer installer, ApexManager apexManager) {
+ mInstaller = installer;
+ mApexManager = apexManager;
}
/**
@@ -55,7 +64,7 @@
@GuardedBy("rollback.mLock")
// TODO(b/136241838): Move into Rollback and synchronize there.
public void snapshotAppData(
- int snapshotId, PackageRollbackInfo packageRollbackInfo, int[] userIds) {
+ int rollbackId, PackageRollbackInfo packageRollbackInfo, int[] userIds) {
for (int user : userIds) {
final int storageFlags;
if (isUserCredentialLocked(user)) {
@@ -68,16 +77,7 @@
storageFlags = Installer.FLAG_STORAGE_CE | Installer.FLAG_STORAGE_DE;
}
- try {
- long ceSnapshotInode = mInstaller.snapshotAppData(
- packageRollbackInfo.getPackageName(), user, snapshotId, storageFlags);
- if ((storageFlags & Installer.FLAG_STORAGE_CE) != 0) {
- packageRollbackInfo.putCeSnapshotInode(user, ceSnapshotInode);
- }
- } catch (InstallerException ie) {
- Slog.e(TAG, "Unable to create app data snapshot for: "
- + packageRollbackInfo.getPackageName() + ", userId: " + user, ie);
- }
+ doSnapshot(packageRollbackInfo, user, rollbackId, storageFlags);
}
}
@@ -119,26 +119,82 @@
}
}
- try {
+ doRestoreOrWipe(packageRollbackInfo, userId, rollbackId, appId, seInfo, storageFlags);
+
+ return changedRollback;
+ }
+
+ private boolean doSnapshot(
+ PackageRollbackInfo packageRollbackInfo, int userId, int rollbackId, int flags) {
+ if (packageRollbackInfo.isApex()) {
+ // For APEX, only snapshot CE here
+ if ((flags & Installer.FLAG_STORAGE_CE) != 0) {
+ long ceSnapshotInode = mApexManager.snapshotCeData(
+ userId, rollbackId, packageRollbackInfo.getPackageName());
+ if (ceSnapshotInode > 0) {
+ packageRollbackInfo.putCeSnapshotInode(userId, ceSnapshotInode);
+ } else {
+ return false;
+ }
+ }
+ } else {
+ // APK
+ try {
+ long ceSnapshotInode = mInstaller.snapshotAppData(
+ packageRollbackInfo.getPackageName(), userId, rollbackId, flags);
+ if ((flags & Installer.FLAG_STORAGE_CE) != 0) {
+ packageRollbackInfo.putCeSnapshotInode(userId, ceSnapshotInode);
+ }
+ } catch (InstallerException ie) {
+ Slog.e(TAG, "Unable to create app data snapshot for: "
+ + packageRollbackInfo.getPackageName() + ", userId: " + userId, ie);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean doRestoreOrWipe(PackageRollbackInfo packageRollbackInfo, int userId,
+ int rollbackId, int appId, String seInfo, int flags) {
+ if (packageRollbackInfo.isApex()) {
switch (packageRollbackInfo.getRollbackDataPolicy()) {
case PackageManager.RollbackDataPolicy.WIPE:
- mInstaller.clearAppData(null, packageRollbackInfo.getPackageName(),
- userId, storageFlags, 0);
+ // TODO: Implement WIPE for apex CE data
break;
case PackageManager.RollbackDataPolicy.RESTORE:
- mInstaller.restoreAppDataSnapshot(packageRollbackInfo.getPackageName(), appId,
- seInfo, userId, rollbackId, storageFlags);
+ // For APEX, only restore of CE may be done here.
+ if ((flags & Installer.FLAG_STORAGE_CE) != 0) {
+ mApexManager.restoreCeData(
+ userId, rollbackId, packageRollbackInfo.getPackageName());
+ }
break;
default:
break;
}
- } catch (InstallerException ie) {
- Slog.e(TAG, "Unable to restore/wipe app data: "
- + packageRollbackInfo.getPackageName() + " policy="
- + packageRollbackInfo.getRollbackDataPolicy(), ie);
- }
+ } else {
+ // APK
+ try {
+ switch (packageRollbackInfo.getRollbackDataPolicy()) {
+ case PackageManager.RollbackDataPolicy.WIPE:
+ mInstaller.clearAppData(null, packageRollbackInfo.getPackageName(),
+ userId, flags, 0);
+ break;
+ case PackageManager.RollbackDataPolicy.RESTORE:
- return changedRollback;
+ mInstaller.restoreAppDataSnapshot(packageRollbackInfo.getPackageName(),
+ appId, seInfo, userId, rollbackId, flags);
+ break;
+ default:
+ break;
+ }
+ } catch (InstallerException ie) {
+ Slog.e(TAG, "Unable to restore/wipe app data: "
+ + packageRollbackInfo.getPackageName() + " policy="
+ + packageRollbackInfo.getRollbackDataPolicy(), ie);
+ return false;
+ }
+ }
+ return true;
}
/**
@@ -204,40 +260,15 @@
if (hasPendingBackup) {
int idx = pendingBackupUsers.indexOf(userId);
- try {
- long ceSnapshotInode = mInstaller.snapshotAppData(info.getPackageName(),
- userId, rollback.info.getRollbackId(),
- Installer.FLAG_STORAGE_CE);
- info.putCeSnapshotInode(userId, ceSnapshotInode);
+ if (doSnapshot(
+ info, userId, rollback.info.getRollbackId(), Installer.FLAG_STORAGE_CE)) {
pendingBackupUsers.remove(idx);
- } catch (InstallerException ie) {
- Slog.e(TAG,
- "Unable to create app data snapshot for: "
- + info.getPackageName() + ", userId: " + userId, ie);
}
}
- if (hasPendingRestore) {
- try {
- switch (info.getRollbackDataPolicy()) {
- case PackageManager.RollbackDataPolicy.WIPE:
- mInstaller.clearAppData(null, info.getPackageName(), userId,
- Installer.FLAG_STORAGE_CE, 0);
- break;
- case PackageManager.RollbackDataPolicy.RESTORE:
- mInstaller.restoreAppDataSnapshot(info.getPackageName(), ri.appId,
- ri.seInfo, userId, rollback.info.getRollbackId(),
- Installer.FLAG_STORAGE_CE);
- break;
- default:
- break;
- }
- info.removeRestoreInfo(ri);
- } catch (InstallerException ie) {
- Slog.e(TAG, "Unable to restore/wipe app data for: "
- + info.getPackageName() + " policy="
- + info.getRollbackDataPolicy(), ie);
- }
+ if (hasPendingRestore && doRestoreOrWipe(info, userId, rollback.info.getRollbackId(),
+ ri.appId, ri.seInfo, Installer.FLAG_STORAGE_CE)) {
+ info.removeRestoreInfo(ri);
}
}
return foundBackupOrRestore;
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index f3197cf..a1d4f42 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -95,7 +95,6 @@
import android.util.Slog;
import android.util.SparseArray;
import android.util.StatsEvent;
-import android.util.StatsLog;
import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.GuardedBy;
@@ -119,6 +118,7 @@
import com.android.internal.os.PowerProfile;
import com.android.internal.os.ProcessCpuTracker;
import com.android.internal.os.StoragedUidIoStatsReader;
+import com.android.internal.util.FrameworkStatsLog;
import com.android.server.BinderCallsStatsService;
import com.android.server.LocalServices;
import com.android.server.SystemService;
@@ -263,115 +263,115 @@
@Override
public int onPullAtom(int atomTag, List<StatsEvent> data) {
switch(atomTag) {
- case StatsLog.WIFI_BYTES_TRANSFER:
+ case FrameworkStatsLog.WIFI_BYTES_TRANSFER:
return pullWifiBytesTransfer(atomTag, data);
- case StatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG:
+ case FrameworkStatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG:
return pullWifiBytesTransferBackground(atomTag, data);
- case StatsLog.MOBILE_BYTES_TRANSFER:
+ case FrameworkStatsLog.MOBILE_BYTES_TRANSFER:
return pullMobileBytesTransfer(atomTag, data);
- case StatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG:
+ case FrameworkStatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG:
return pullMobileBytesTransferBackground(atomTag, data);
- case StatsLog.BLUETOOTH_BYTES_TRANSFER:
+ case FrameworkStatsLog.BLUETOOTH_BYTES_TRANSFER:
return pullBluetoothBytesTransfer(atomTag, data);
- case StatsLog.KERNEL_WAKELOCK:
+ case FrameworkStatsLog.KERNEL_WAKELOCK:
return pullKernelWakelock(atomTag, data);
- case StatsLog.CPU_TIME_PER_FREQ:
+ case FrameworkStatsLog.CPU_TIME_PER_FREQ:
return pullCpuTimePerFreq(atomTag, data);
- case StatsLog.CPU_TIME_PER_UID:
+ case FrameworkStatsLog.CPU_TIME_PER_UID:
return pullCpuTimePerUid(atomTag, data);
- case StatsLog.CPU_TIME_PER_UID_FREQ:
+ case FrameworkStatsLog.CPU_TIME_PER_UID_FREQ:
return pullCpuTimeperUidFreq(atomTag, data);
- case StatsLog.CPU_ACTIVE_TIME:
+ case FrameworkStatsLog.CPU_ACTIVE_TIME:
return pullCpuActiveTime(atomTag, data);
- case StatsLog.CPU_CLUSTER_TIME:
+ case FrameworkStatsLog.CPU_CLUSTER_TIME:
return pullCpuClusterTime(atomTag, data);
- case StatsLog.WIFI_ACTIVITY_INFO:
+ case FrameworkStatsLog.WIFI_ACTIVITY_INFO:
return pullWifiActivityInfo(atomTag, data);
- case StatsLog.MODEM_ACTIVITY_INFO:
+ case FrameworkStatsLog.MODEM_ACTIVITY_INFO:
return pullModemActivityInfo(atomTag, data);
- case StatsLog.BLUETOOTH_ACTIVITY_INFO:
+ case FrameworkStatsLog.BLUETOOTH_ACTIVITY_INFO:
return pullBluetoothActivityInfo(atomTag, data);
- case StatsLog.SYSTEM_ELAPSED_REALTIME:
+ case FrameworkStatsLog.SYSTEM_ELAPSED_REALTIME:
return pullSystemElapsedRealtime(atomTag, data);
- case StatsLog.SYSTEM_UPTIME:
+ case FrameworkStatsLog.SYSTEM_UPTIME:
return pullSystemUptime(atomTag, data);
- case StatsLog.PROCESS_MEMORY_STATE:
+ case FrameworkStatsLog.PROCESS_MEMORY_STATE:
return pullProcessMemoryState(atomTag, data);
- case StatsLog.PROCESS_MEMORY_HIGH_WATER_MARK:
+ case FrameworkStatsLog.PROCESS_MEMORY_HIGH_WATER_MARK:
return pullProcessMemoryHighWaterMark(atomTag, data);
- case StatsLog.PROCESS_MEMORY_SNAPSHOT:
+ case FrameworkStatsLog.PROCESS_MEMORY_SNAPSHOT:
return pullProcessMemorySnapshot(atomTag, data);
- case StatsLog.SYSTEM_ION_HEAP_SIZE:
+ case FrameworkStatsLog.SYSTEM_ION_HEAP_SIZE:
return pullSystemIonHeapSize(atomTag, data);
- case StatsLog.ION_HEAP_SIZE:
+ case FrameworkStatsLog.ION_HEAP_SIZE:
return pullIonHeapSize(atomTag, data);
- case StatsLog.PROCESS_SYSTEM_ION_HEAP_SIZE:
+ case FrameworkStatsLog.PROCESS_SYSTEM_ION_HEAP_SIZE:
return pullProcessSystemIonHeapSize(atomTag, data);
- case StatsLog.TEMPERATURE:
+ case FrameworkStatsLog.TEMPERATURE:
return pullTemperature(atomTag, data);
- case StatsLog.COOLING_DEVICE:
+ case FrameworkStatsLog.COOLING_DEVICE:
return pullCooldownDevice(atomTag, data);
- case StatsLog.BINDER_CALLS:
+ case FrameworkStatsLog.BINDER_CALLS:
return pullBinderCallsStats(atomTag, data);
- case StatsLog.BINDER_CALLS_EXCEPTIONS:
+ case FrameworkStatsLog.BINDER_CALLS_EXCEPTIONS:
return pullBinderCallsStatsExceptions(atomTag, data);
- case StatsLog.LOOPER_STATS:
+ case FrameworkStatsLog.LOOPER_STATS:
return pullLooperStats(atomTag, data);
- case StatsLog.DISK_STATS:
+ case FrameworkStatsLog.DISK_STATS:
return pullDiskStats(atomTag, data);
- case StatsLog.DIRECTORY_USAGE:
+ case FrameworkStatsLog.DIRECTORY_USAGE:
return pullDirectoryUsage(atomTag, data);
- case StatsLog.APP_SIZE:
+ case FrameworkStatsLog.APP_SIZE:
return pullAppSize(atomTag, data);
- case StatsLog.CATEGORY_SIZE:
+ case FrameworkStatsLog.CATEGORY_SIZE:
return pullCategorySize(atomTag, data);
- case StatsLog.NUM_FINGERPRINTS_ENROLLED:
+ case FrameworkStatsLog.NUM_FINGERPRINTS_ENROLLED:
return pullNumBiometricsEnrolled(
BiometricsProtoEnums.MODALITY_FINGERPRINT, atomTag, data);
- case StatsLog.NUM_FACES_ENROLLED:
+ case FrameworkStatsLog.NUM_FACES_ENROLLED:
return pullNumBiometricsEnrolled(
BiometricsProtoEnums.MODALITY_FACE, atomTag, data);
- case StatsLog.PROC_STATS:
+ case FrameworkStatsLog.PROC_STATS:
return pullProcStats(ProcessStats.REPORT_ALL, atomTag, data);
- case StatsLog.PROC_STATS_PKG_PROC:
+ case FrameworkStatsLog.PROC_STATS_PKG_PROC:
return pullProcStats(ProcessStats.REPORT_PKG_PROC_STATS, atomTag, data);
- case StatsLog.DISK_IO:
+ case FrameworkStatsLog.DISK_IO:
return pullDiskIO(atomTag, data);
- case StatsLog.POWER_PROFILE:
+ case FrameworkStatsLog.POWER_PROFILE:
return pullPowerProfile(atomTag, data);
- case StatsLog.PROCESS_CPU_TIME:
+ case FrameworkStatsLog.PROCESS_CPU_TIME:
return pullProcessCpuTime(atomTag, data);
- case StatsLog.CPU_TIME_PER_THREAD_FREQ:
+ case FrameworkStatsLog.CPU_TIME_PER_THREAD_FREQ:
return pullCpuTimePerThreadFreq(atomTag, data);
- case StatsLog.DEVICE_CALCULATED_POWER_USE:
+ case FrameworkStatsLog.DEVICE_CALCULATED_POWER_USE:
return pullDeviceCalculatedPowerUse(atomTag, data);
- case StatsLog.DEVICE_CALCULATED_POWER_BLAME_UID:
+ case FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_UID:
return pullDeviceCalculatedPowerBlameUid(atomTag, data);
- case StatsLog.DEVICE_CALCULATED_POWER_BLAME_OTHER:
+ case FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_OTHER:
return pullDeviceCalculatedPowerBlameOther(atomTag, data);
- case StatsLog.DEBUG_ELAPSED_CLOCK:
+ case FrameworkStatsLog.DEBUG_ELAPSED_CLOCK:
return pullDebugElapsedClock(atomTag, data);
- case StatsLog.DEBUG_FAILING_ELAPSED_CLOCK:
+ case FrameworkStatsLog.DEBUG_FAILING_ELAPSED_CLOCK:
return pullDebugFailingElapsedClock(atomTag, data);
- case StatsLog.BUILD_INFORMATION:
+ case FrameworkStatsLog.BUILD_INFORMATION:
return pullBuildInformation(atomTag, data);
- case StatsLog.ROLE_HOLDER:
+ case FrameworkStatsLog.ROLE_HOLDER:
return pullRoleHolder(atomTag, data);
- case StatsLog.DANGEROUS_PERMISSION_STATE:
+ case FrameworkStatsLog.DANGEROUS_PERMISSION_STATE:
return pullDangerousPermissionState(atomTag, data);
- case StatsLog.TIME_ZONE_DATA_INFO:
+ case FrameworkStatsLog.TIME_ZONE_DATA_INFO:
return pullTimeZoneDataInfo(atomTag, data);
- case StatsLog.EXTERNAL_STORAGE_INFO:
+ case FrameworkStatsLog.EXTERNAL_STORAGE_INFO:
return pullExternalStorageInfo(atomTag, data);
- case StatsLog.APPS_ON_EXTERNAL_STORAGE_INFO:
+ case FrameworkStatsLog.APPS_ON_EXTERNAL_STORAGE_INFO:
return pullAppsOnExternalStorageInfo(atomTag, data);
- case StatsLog.FACE_SETTINGS:
+ case FrameworkStatsLog.FACE_SETTINGS:
return pullFaceSettings(atomTag, data);
- case StatsLog.APP_OPS:
+ case FrameworkStatsLog.APP_OPS:
return pullAppOps(atomTag, data);
- case StatsLog.NOTIFICATION_REMOTE_VIEWS:
+ case FrameworkStatsLog.NOTIFICATION_REMOTE_VIEWS:
return pullNotificationRemoteViews(atomTag, data);
- case StatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED:
+ case FrameworkStatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED:
return pullDangerousPermissionState(atomTag, data);
default:
throw new UnsupportedOperationException("Unknown tagId=" + atomTag);
@@ -633,7 +633,7 @@
}
private void registerWifiBytesTransfer() {
- int tagId = StatsLog.WIFI_BYTES_TRANSFER;
+ int tagId = FrameworkStatsLog.WIFI_BYTES_TRANSFER;
PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setAdditiveFields(new int[] {2, 3, 4, 5})
.build();
@@ -725,7 +725,7 @@
}
private void registerWifiBytesTransferBackground() {
- int tagId = StatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG;
+ int tagId = FrameworkStatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG;
PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setAdditiveFields(new int[] {3, 4, 5, 6})
.build();
@@ -763,7 +763,7 @@
}
private void registerMobileBytesTransfer() {
- int tagId = StatsLog.MOBILE_BYTES_TRANSFER;
+ int tagId = FrameworkStatsLog.MOBILE_BYTES_TRANSFER;
PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setAdditiveFields(new int[] {2, 3, 4, 5})
.build();
@@ -801,7 +801,7 @@
}
private void registerMobileBytesTransferBackground() {
- int tagId = StatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG;
+ int tagId = FrameworkStatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG;
PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setAdditiveFields(new int[] {3, 4, 5, 6})
.build();
@@ -839,7 +839,7 @@
}
private void registerBluetoothBytesTransfer() {
- int tagId = StatsLog.BLUETOOTH_BYTES_TRANSFER;
+ int tagId = FrameworkStatsLog.BLUETOOTH_BYTES_TRANSFER;
PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setAdditiveFields(new int[] {2, 3})
.build();
@@ -912,7 +912,7 @@
}
private void registerKernelWakelock() {
- int tagId = StatsLog.KERNEL_WAKELOCK;
+ int tagId = FrameworkStatsLog.KERNEL_WAKELOCK;
mStatsManager.registerPullAtomCallback(
tagId,
/* PullAtomMetadata */ null,
@@ -940,7 +940,7 @@
}
private void registerCpuTimePerFreq() {
- int tagId = StatsLog.CPU_TIME_PER_FREQ;
+ int tagId = FrameworkStatsLog.CPU_TIME_PER_FREQ;
PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setAdditiveFields(new int[] {3})
.build();
@@ -971,7 +971,7 @@
}
private void registerCpuTimePerUid() {
- int tagId = StatsLog.CPU_TIME_PER_UID;
+ int tagId = FrameworkStatsLog.CPU_TIME_PER_UID;
PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setAdditiveFields(new int[] {2, 3})
.build();
@@ -1000,7 +1000,7 @@
private void registerCpuTimePerUidFreq() {
// the throttling is 3sec, handled in
// frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
- int tagId = StatsLog.CPU_TIME_PER_UID_FREQ;
+ int tagId = FrameworkStatsLog.CPU_TIME_PER_UID_FREQ;
PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setAdditiveFields(new int[] {4})
.build();
@@ -1032,7 +1032,7 @@
private void registerCpuActiveTime() {
// the throttling is 3sec, handled in
// frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
- int tagId = StatsLog.CPU_ACTIVE_TIME;
+ int tagId = FrameworkStatsLog.CPU_ACTIVE_TIME;
PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setAdditiveFields(new int[] {2})
.build();
@@ -1059,7 +1059,7 @@
private void registerCpuClusterTime() {
// the throttling is 3sec, handled in
// frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
- int tagId = StatsLog.CPU_CLUSTER_TIME;
+ int tagId = FrameworkStatsLog.CPU_CLUSTER_TIME;
PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setAdditiveFields(new int[] {3})
.build();
@@ -1087,7 +1087,7 @@
}
private void registerWifiActivityInfo() {
- int tagId = StatsLog.WIFI_ACTIVITY_INFO;
+ int tagId = FrameworkStatsLog.WIFI_ACTIVITY_INFO;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -1139,7 +1139,7 @@
}
private void registerModemActivityInfo() {
- int tagId = StatsLog.MODEM_ACTIVITY_INFO;
+ int tagId = FrameworkStatsLog.MODEM_ACTIVITY_INFO;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -1177,7 +1177,7 @@
}
private void registerBluetoothActivityInfo() {
- int tagId = StatsLog.BLUETOOTH_ACTIVITY_INFO;
+ int tagId = FrameworkStatsLog.BLUETOOTH_ACTIVITY_INFO;
mStatsManager.registerPullAtomCallback(
tagId,
/* metadata */ null,
@@ -1205,7 +1205,7 @@
}
private void registerSystemElapsedRealtime() {
- int tagId = StatsLog.SYSTEM_ELAPSED_REALTIME;
+ int tagId = FrameworkStatsLog.SYSTEM_ELAPSED_REALTIME;
PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setCoolDownNs(NS_PER_SEC)
.setTimeoutNs(NS_PER_SEC / 2)
@@ -1228,7 +1228,7 @@
}
private void registerSystemUptime() {
- int tagId = StatsLog.SYSTEM_UPTIME;
+ int tagId = FrameworkStatsLog.SYSTEM_UPTIME;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -1247,7 +1247,7 @@
}
private void registerProcessMemoryState() {
- int tagId = StatsLog.PROCESS_MEMORY_STATE;
+ int tagId = FrameworkStatsLog.PROCESS_MEMORY_STATE;
PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setAdditiveFields(new int[] {4, 5, 6, 7, 8})
.build();
@@ -1293,7 +1293,7 @@
}
private void registerProcessMemoryHighWaterMark() {
- int tagId = StatsLog.PROCESS_MEMORY_HIGH_WATER_MARK;
+ int tagId = FrameworkStatsLog.PROCESS_MEMORY_HIGH_WATER_MARK;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -1346,7 +1346,7 @@
}
private void registerProcessMemorySnapshot() {
- int tagId = StatsLog.PROCESS_MEMORY_SNAPSHOT;
+ int tagId = FrameworkStatsLog.PROCESS_MEMORY_SNAPSHOT;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -1406,7 +1406,7 @@
}
private void registerSystemIonHeapSize() {
- int tagId = StatsLog.SYSTEM_ION_HEAP_SIZE;
+ int tagId = FrameworkStatsLog.SYSTEM_ION_HEAP_SIZE;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -1426,7 +1426,7 @@
}
private void registerIonHeapSize() {
- int tagId = StatsLog.ION_HEAP_SIZE;
+ int tagId = FrameworkStatsLog.ION_HEAP_SIZE;
mStatsManager.registerPullAtomCallback(
tagId,
/* PullAtomMetadata */ null,
@@ -1446,7 +1446,7 @@
}
private void registerProcessSystemIonHeapSize() {
- int tagId = StatsLog.PROCESS_SYSTEM_ION_HEAP_SIZE;
+ int tagId = FrameworkStatsLog.PROCESS_SYSTEM_ION_HEAP_SIZE;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -1472,7 +1472,7 @@
}
private void registerTemperature() {
- int tagId = StatsLog.TEMPERATURE;
+ int tagId = FrameworkStatsLog.TEMPERATURE;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -1510,7 +1510,7 @@
}
private void registerCoolingDevice() {
- int tagId = StatsLog.COOLING_DEVICE;
+ int tagId = FrameworkStatsLog.COOLING_DEVICE;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -1547,7 +1547,7 @@
}
private void registerBinderCallsStats() {
- int tagId = StatsLog.BINDER_CALLS;
+ int tagId = FrameworkStatsLog.BINDER_CALLS;
PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setAdditiveFields(new int[] {4, 5, 6, 8, 12})
.build();
@@ -1593,7 +1593,7 @@
}
private void registerBinderCallsStatsExceptions() {
- int tagId = StatsLog.BINDER_CALLS_EXCEPTIONS;
+ int tagId = FrameworkStatsLog.BINDER_CALLS_EXCEPTIONS;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -1625,7 +1625,7 @@
}
private void registerLooperStats() {
- int tagId = StatsLog.LOOPER_STATS;
+ int tagId = FrameworkStatsLog.LOOPER_STATS;
PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setAdditiveFields(new int[] {5, 6, 7, 8, 9})
.build();
@@ -1670,7 +1670,7 @@
}
private void registerDiskStats() {
- int tagId = StatsLog.DISK_STATS;
+ int tagId = FrameworkStatsLog.DISK_STATS;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -1736,7 +1736,7 @@
}
private void registerDirectoryUsage() {
- int tagId = StatsLog.DIRECTORY_USAGE;
+ int tagId = FrameworkStatsLog.DIRECTORY_USAGE;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -1752,7 +1752,7 @@
StatsEvent e = StatsEvent.newBuilder()
.setAtomId(atomTag)
- .writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__DATA)
+ .writeInt(FrameworkStatsLog.DIRECTORY_USAGE__DIRECTORY__DATA)
.writeLong(statFsData.getAvailableBytes())
.writeLong(statFsData.getTotalBytes())
.build();
@@ -1760,7 +1760,7 @@
e = StatsEvent.newBuilder()
.setAtomId(atomTag)
- .writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__CACHE)
+ .writeInt(FrameworkStatsLog.DIRECTORY_USAGE__DIRECTORY__CACHE)
.writeLong(statFsCache.getAvailableBytes())
.writeLong(statFsCache.getTotalBytes())
.build();
@@ -1768,7 +1768,7 @@
e = StatsEvent.newBuilder()
.setAtomId(atomTag)
- .writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__SYSTEM)
+ .writeInt(FrameworkStatsLog.DIRECTORY_USAGE__DIRECTORY__SYSTEM)
.writeLong(statFsSystem.getAvailableBytes())
.writeLong(statFsSystem.getTotalBytes())
.build();
@@ -1777,7 +1777,7 @@
}
private void registerAppSize() {
- int tagId = StatsLog.APP_SIZE;
+ int tagId = FrameworkStatsLog.APP_SIZE;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -1821,7 +1821,7 @@
}
private void registerCategorySize() {
- int tagId = StatsLog.CATEGORY_SIZE;
+ int tagId = FrameworkStatsLog.CATEGORY_SIZE;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -1839,7 +1839,7 @@
StatsEvent e = StatsEvent.newBuilder()
.setAtomId(atomTag)
- .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_SIZE)
+ .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__APP_SIZE)
.writeLong(json.optLong(
DiskStatsFileLogger.APP_SIZE_AGG_KEY, /* fallback */ -1L))
.writeLong(cacheTime)
@@ -1848,7 +1848,7 @@
e = StatsEvent.newBuilder()
.setAtomId(atomTag)
- .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_DATA_SIZE)
+ .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__APP_DATA_SIZE)
.writeLong(json.optLong(
DiskStatsFileLogger.APP_DATA_SIZE_AGG_KEY, /* fallback */ -1L))
.writeLong(cacheTime)
@@ -1857,7 +1857,7 @@
e = StatsEvent.newBuilder()
.setAtomId(atomTag)
- .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_CACHE_SIZE)
+ .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__APP_CACHE_SIZE)
.writeLong(json.optLong(
DiskStatsFileLogger.APP_CACHE_AGG_KEY, /* fallback */ -1L))
.writeLong(cacheTime)
@@ -1866,7 +1866,7 @@
e = StatsEvent.newBuilder()
.setAtomId(atomTag)
- .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__PHOTOS)
+ .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__PHOTOS)
.writeLong(json.optLong(
DiskStatsFileLogger.PHOTOS_KEY, /* fallback */ -1L))
.writeLong(cacheTime)
@@ -1875,7 +1875,7 @@
e = StatsEvent.newBuilder()
.setAtomId(atomTag)
- .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__VIDEOS)
+ .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__VIDEOS)
.writeLong(
json.optLong(DiskStatsFileLogger.VIDEOS_KEY, /* fallback */ -1L))
.writeLong(cacheTime)
@@ -1884,7 +1884,7 @@
e = StatsEvent.newBuilder()
.setAtomId(atomTag)
- .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__AUDIO)
+ .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__AUDIO)
.writeLong(json.optLong(
DiskStatsFileLogger.AUDIO_KEY, /* fallback */ -1L))
.writeLong(cacheTime)
@@ -1893,7 +1893,7 @@
e = StatsEvent.newBuilder()
.setAtomId(atomTag)
- .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__DOWNLOADS)
+ .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__DOWNLOADS)
.writeLong(
json.optLong(DiskStatsFileLogger.DOWNLOADS_KEY, /* fallback */ -1L))
.writeLong(cacheTime)
@@ -1901,7 +1901,8 @@
pulledData.add(e);
e = StatsEvent.newBuilder()
- .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__SYSTEM)
+ .setAtomId(atomTag)
+ .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__SYSTEM)
.writeLong(json.optLong(
DiskStatsFileLogger.SYSTEM_KEY, /* fallback */ -1L))
.writeLong(cacheTime)
@@ -1910,7 +1911,7 @@
e = StatsEvent.newBuilder()
.setAtomId(atomTag)
- .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__OTHER)
+ .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__OTHER)
.writeLong(json.optLong(
DiskStatsFileLogger.MISC_KEY, /* fallback */ -1L))
.writeLong(cacheTime)
@@ -1924,7 +1925,7 @@
}
private void registerNumFingerprintsEnrolled() {
- int tagId = StatsLog.NUM_FINGERPRINTS_ENROLLED;
+ int tagId = FrameworkStatsLog.NUM_FINGERPRINTS_ENROLLED;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -1934,7 +1935,7 @@
}
private void registerNumFacesEnrolled() {
- int tagId = StatsLog.NUM_FACES_ENROLLED;
+ int tagId = FrameworkStatsLog.NUM_FACES_ENROLLED;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -1992,7 +1993,7 @@
}
private void registerProcStats() {
- int tagId = StatsLog.PROC_STATS;
+ int tagId = FrameworkStatsLog.PROC_STATS;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -2002,7 +2003,7 @@
}
private void registerProcStatsPkgProc() {
- int tagId = StatsLog.PROC_STATS_PKG_PROC;
+ int tagId = FrameworkStatsLog.PROC_STATS_PKG_PROC;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -2071,7 +2072,7 @@
}
private void registerDiskIO() {
- int tagId = StatsLog.DISK_IO;
+ int tagId = FrameworkStatsLog.DISK_IO;
PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setAdditiveFields(new int[] {2, 3, 4, 5, 6, 7, 8, 9, 10, 11})
.setCoolDownNs(3 * NS_PER_SEC)
@@ -2108,7 +2109,7 @@
}
private void registerPowerProfile() {
- int tagId = StatsLog.POWER_PROFILE;
+ int tagId = FrameworkStatsLog.POWER_PROFILE;
mStatsManager.registerPullAtomCallback(
tagId,
/* PullAtomMetadata */ null,
@@ -2131,7 +2132,7 @@
}
private void registerProcessCpuTime() {
- int tagId = StatsLog.PROCESS_CPU_TIME;
+ int tagId = FrameworkStatsLog.PROCESS_CPU_TIME;
// Min cool-down is 5 sec, in line with what ActivityManagerService uses.
PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setCoolDownNs(5 * NS_PER_SEC)
@@ -2167,7 +2168,7 @@
}
private void registerCpuTimePerThreadFreq() {
- int tagId = StatsLog.CPU_TIME_PER_THREAD_FREQ;
+ int tagId = FrameworkStatsLog.CPU_TIME_PER_THREAD_FREQ;
PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setAdditiveFields(new int[] {7, 9, 11, 13, 15, 17, 19, 21})
.build();
@@ -2263,7 +2264,7 @@
}
private void registerDeviceCalculatedPowerUse() {
- int tagId = StatsLog.DEVICE_CALCULATED_POWER_USE;
+ int tagId = FrameworkStatsLog.DEVICE_CALCULATED_POWER_USE;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -2283,7 +2284,7 @@
}
private void registerDeviceCalculatedPowerBlameUid() {
- int tagId = StatsLog.DEVICE_CALCULATED_POWER_BLAME_UID;
+ int tagId = FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_UID;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -2313,7 +2314,7 @@
}
private void registerDeviceCalculatedPowerBlameOther() {
- int tagId = StatsLog.DEVICE_CALCULATED_POWER_BLAME_OTHER;
+ int tagId = FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_OTHER;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -2346,7 +2347,7 @@
}
private void registerDebugElapsedClock() {
- int tagId = StatsLog.DEBUG_ELAPSED_CLOCK;
+ int tagId = FrameworkStatsLog.DEBUG_ELAPSED_CLOCK;
PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setAdditiveFields(new int[] {1, 2, 3, 4})
.build();
@@ -2397,7 +2398,7 @@
}
private void registerDebugFailingElapsedClock() {
- int tagId = StatsLog.DEBUG_FAILING_ELAPSED_CLOCK;
+ int tagId = FrameworkStatsLog.DEBUG_FAILING_ELAPSED_CLOCK;
PullAtomMetadata metadata = new PullAtomMetadata.Builder()
.setAdditiveFields(new int[] {1, 2, 3, 4})
.build();
@@ -2438,7 +2439,7 @@
}
private void registerBuildInformation() {
- int tagId = StatsLog.BUILD_INFORMATION;
+ int tagId = FrameworkStatsLog.BUILD_INFORMATION;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -2465,7 +2466,7 @@
}
private void registerRoleHolder() {
- int tagId = StatsLog.ROLE_HOLDER;
+ int tagId = FrameworkStatsLog.ROLE_HOLDER;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -2523,7 +2524,7 @@
}
private void registerDangerousPermissionState() {
- int tagId = StatsLog.DANGEROUS_PERMISSION_STATE;
+ int tagId = FrameworkStatsLog.DANGEROUS_PERMISSION_STATE;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -2561,7 +2562,7 @@
}
reportedUids.add(pkg.applicationInfo.uid);
- if (atomTag == StatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED
+ if (atomTag == FrameworkStatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED
&& ThreadLocalRandom.current().nextFloat() > 0.01f) {
continue;
}
@@ -2588,7 +2589,7 @@
e.setAtomId(atomTag);
e.writeString(permName);
e.writeInt(pkg.applicationInfo.uid);
- if (atomTag == StatsLog.DANGEROUS_PERMISSION_STATE) {
+ if (atomTag == FrameworkStatsLog.DANGEROUS_PERMISSION_STATE) {
e.writeString("");
}
e.writeBoolean((pkg.requestedPermissionsFlags[permNum]
@@ -2609,7 +2610,7 @@
}
private void registerTimeZoneDataInfo() {
- int tagId = StatsLog.TIME_ZONE_DATA_INFO;
+ int tagId = FrameworkStatsLog.TIME_ZONE_DATA_INFO;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -2636,7 +2637,7 @@
}
private void registerExternalStorageInfo() {
- int tagId = StatsLog.EXTERNAL_STORAGE_INFO;
+ int tagId = FrameworkStatsLog.EXTERNAL_STORAGE_INFO;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -2656,11 +2657,11 @@
final DiskInfo diskInfo = vol.getDisk();
if (diskInfo != null && envState.equals(Environment.MEDIA_MOUNTED)) {
// Get the type of the volume, if it is adoptable or portable.
- int volumeType = StatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__OTHER;
+ int volumeType = FrameworkStatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__OTHER;
if (vol.getType() == TYPE_PUBLIC) {
- volumeType = StatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PUBLIC;
+ volumeType = FrameworkStatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PUBLIC;
} else if (vol.getType() == TYPE_PRIVATE) {
- volumeType = StatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PRIVATE;
+ volumeType = FrameworkStatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PRIVATE;
}
// Get the type of external storage inserted in the device (sd cards, usb, etc.)
@@ -2686,7 +2687,7 @@
}
private void registerAppsOnExternalStorageInfo() {
- int tagId = StatsLog.APPS_ON_EXTERNAL_STORAGE_INFO;
+ int tagId = FrameworkStatsLog.APPS_ON_EXTERNAL_STORAGE_INFO;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -2742,7 +2743,7 @@
}
private void registerFaceSettings() {
- int tagId = StatsLog.FACE_SETTINGS;
+ int tagId = FrameworkStatsLog.FACE_SETTINGS;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -2796,7 +2797,7 @@
}
private void registerAppOps() {
- int tagId = StatsLog.APP_OPS;
+ int tagId = FrameworkStatsLog.APP_OPS;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -2907,7 +2908,7 @@
}
private void registerNotificationRemoteViews() {
- int tagId = StatsLog.NOTIFICATION_REMOTE_VIEWS;
+ int tagId = FrameworkStatsLog.NOTIFICATION_REMOTE_VIEWS;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -2951,7 +2952,7 @@
}
private void registerDangerousPermissionStateSampled() {
- int tagId = StatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED;
+ int tagId = FrameworkStatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
@@ -2965,8 +2966,8 @@
private static final class ThermalEventListener extends IThermalEventListener.Stub {
@Override
public void notifyThrottling(Temperature temp) {
- StatsLog.write(StatsLog.THERMAL_THROTTLING_SEVERITY_STATE_CHANGED, temp.getType(),
- temp.getName(), (int) (temp.getValue() * 10), temp.getStatus());
+ FrameworkStatsLog.write(FrameworkStatsLog.THERMAL_THROTTLING_SEVERITY_STATE_CHANGED,
+ temp.getType(), temp.getName(), (int) (temp.getValue() * 10), temp.getStatus());
}
}
@@ -2974,14 +2975,14 @@
ConnectivityManager.NetworkCallback {
@Override
public void onAvailable(Network network) {
- StatsLog.write(StatsLog.CONNECTIVITY_STATE_CHANGED, network.netId,
- StatsLog.CONNECTIVITY_STATE_CHANGED__STATE__CONNECTED);
+ FrameworkStatsLog.write(FrameworkStatsLog.CONNECTIVITY_STATE_CHANGED, network.netId,
+ FrameworkStatsLog.CONNECTIVITY_STATE_CHANGED__STATE__CONNECTED);
}
@Override
public void onLost(Network network) {
- StatsLog.write(StatsLog.CONNECTIVITY_STATE_CHANGED, network.netId,
- StatsLog.CONNECTIVITY_STATE_CHANGED__STATE__DISCONNECTED);
+ FrameworkStatsLog.write(FrameworkStatsLog.CONNECTIVITY_STATE_CHANGED, network.netId,
+ FrameworkStatsLog.CONNECTIVITY_STATE_CHANGED__STATE__DISCONNECTED);
}
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index 23b94bd..2ef0015 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -83,13 +83,13 @@
import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
-import android.util.StatsLog;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.LocalServices;
@@ -768,8 +768,8 @@
builder.setType(type);
builder.addTaggedData(FIELD_CLASS_NAME, activity.info.name);
mMetricsLogger.write(builder);
- StatsLog.write(
- StatsLog.APP_START_CANCELED,
+ FrameworkStatsLog.write(
+ FrameworkStatsLog.APP_START_CANCELED,
activity.info.applicationInfo.uid,
activity.packageName,
convertAppStartTransitionType(type),
@@ -844,8 +844,8 @@
builder.addTaggedData(PACKAGE_OPTIMIZATION_COMPILATION_FILTER,
packageOptimizationInfo.getCompilationFilter());
mMetricsLogger.write(builder);
- StatsLog.write(
- StatsLog.APP_START_OCCURRED,
+ FrameworkStatsLog.write(
+ FrameworkStatsLog.APP_START_OCCURRED,
info.applicationInfo.uid,
info.packageName,
convertAppStartTransitionType(info.type),
@@ -895,15 +895,15 @@
private int convertAppStartTransitionType(int tronType) {
if (tronType == TYPE_TRANSITION_COLD_LAUNCH) {
- return StatsLog.APP_START_OCCURRED__TYPE__COLD;
+ return FrameworkStatsLog.APP_START_OCCURRED__TYPE__COLD;
}
if (tronType == TYPE_TRANSITION_WARM_LAUNCH) {
- return StatsLog.APP_START_OCCURRED__TYPE__WARM;
+ return FrameworkStatsLog.APP_START_OCCURRED__TYPE__WARM;
}
if (tronType == TYPE_TRANSITION_HOT_LAUNCH) {
- return StatsLog.APP_START_OCCURRED__TYPE__HOT;
+ return FrameworkStatsLog.APP_START_OCCURRED__TYPE__HOT;
}
- return StatsLog.APP_START_OCCURRED__TYPE__UNKNOWN;
+ return FrameworkStatsLog.APP_START_OCCURRED__TYPE__UNKNOWN;
}
/** @return the last known window drawn delay of the given activity. */
@@ -957,13 +957,13 @@
builder.addTaggedData(APP_TRANSITION_PROCESS_RUNNING,
info.mProcessRunning ? 1 : 0);
mMetricsLogger.write(builder);
- StatsLog.write(
- StatsLog.APP_START_FULLY_DRAWN,
+ FrameworkStatsLog.write(
+ FrameworkStatsLog.APP_START_FULLY_DRAWN,
info.mLastLaunchedActivity.info.applicationInfo.uid,
info.mLastLaunchedActivity.packageName,
restoredFromBundle
- ? StatsLog.APP_START_FULLY_DRAWN__TYPE__WITH_BUNDLE
- : StatsLog.APP_START_FULLY_DRAWN__TYPE__WITHOUT_BUNDLE,
+ ? FrameworkStatsLog.APP_START_FULLY_DRAWN__TYPE__WITH_BUNDLE
+ : FrameworkStatsLog.APP_START_FULLY_DRAWN__TYPE__WITHOUT_BUNDLE,
info.mLastLaunchedActivity.info.name,
info.mProcessRunning,
startupTimeMs);
@@ -1068,8 +1068,8 @@
return;
}
- StatsLog.write(
- StatsLog.APP_START_MEMORY_STATE_CAPTURED,
+ FrameworkStatsLog.write(
+ FrameworkStatsLog.APP_START_MEMORY_STATE_CAPTURED,
uid,
info.processName,
info.launchedActivityName,
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 976fbdb..f019013 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -222,7 +222,6 @@
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
-import android.util.StatsLog;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
import android.view.IRecentsAnimationRunner;
@@ -248,6 +247,7 @@
import com.android.internal.policy.KeyguardDismissCallback;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastPrintWriter;
+import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.function.pooled.PooledConsumer;
import com.android.internal.util.function.pooled.PooledFunction;
import com.android.internal.util.function.pooled.PooledLambda;
@@ -5380,7 +5380,7 @@
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
"Updating global configuration to: " + values);
writeConfigurationChanged(changes);
- StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
+ FrameworkStatsLog.write(FrameworkStatsLog.RESOURCE_CONFIGURATION_CHANGED,
values.colorMode,
values.densityDpi,
values.fontScale,
@@ -5699,8 +5699,8 @@
// will wake up stacks or put them to sleep as appropriate.
if (wasSleeping) {
mSleeping = false;
- StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
- StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__AWAKE);
+ FrameworkStatsLog.write(FrameworkStatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
+ FrameworkStatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__AWAKE);
startTimeTrackingFocusedActivityLocked();
mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
Slog.d(TAG, "Top Process State changed to PROCESS_STATE_TOP");
@@ -5712,8 +5712,8 @@
}
} else if (!mSleeping && shouldSleep) {
mSleeping = true;
- StatsLog.write(StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
- StatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__ASLEEP);
+ FrameworkStatsLog.write(FrameworkStatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED,
+ FrameworkStatsLog.ACTIVITY_MANAGER_SLEEP_STATE_CHANGED__STATE__ASLEEP);
if (mCurAppTimeTracker != null) {
mCurAppTimeTracker.stop();
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index c50048e..8574672 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1244,6 +1244,11 @@
return mDisplayRotation;
}
+ void setInsetProvider(@InternalInsetsType int type, WindowState win,
+ @Nullable TriConsumer<DisplayFrames, WindowState, Rect> frameProvider){
+ setInsetProvider(type, win, frameProvider, null /* imeFrameProvider */);
+ }
+
/**
* Marks a window as providing insets for the rest of the windows in the system.
*
@@ -1251,10 +1256,14 @@
* @param win The window.
* @param frameProvider Function to compute the frame, or {@code null} if the just the frame of
* the window should be taken.
+ * @param imeFrameProvider Function to compute the frame when dispatching insets to the IME, or
+ * {@code null} if the normal frame should be taken.
*/
void setInsetProvider(@InternalInsetsType int type, WindowState win,
- @Nullable TriConsumer<DisplayFrames, WindowState, Rect> frameProvider) {
- mInsetsStateController.getSourceProvider(type).setWindow(win, frameProvider);
+ @Nullable TriConsumer<DisplayFrames, WindowState, Rect> frameProvider,
+ @Nullable TriConsumer<DisplayFrames, WindowState, Rect> imeFrameProvider) {
+ mInsetsStateController.getSourceProvider(type).setWindow(win, frameProvider,
+ imeFrameProvider);
}
InsetsStateController getInsetsStateController() {
@@ -3283,7 +3292,7 @@
}
computeImeTarget(true /* updateImeTarget */);
mInsetsStateController.getSourceProvider(ITYPE_IME).setWindow(win,
- null /* frameProvider */);
+ null /* frameProvider */, null /* imeFrameProvider */);
}
/**
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index c6ccd4a..67d8acf 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -1026,7 +1026,12 @@
- getNavigationBarHeight(displayFrames.mRotation,
mDisplayContent.getConfiguration().uiMode);
}
- });
+ },
+
+ // For IME we use regular frame.
+ (displayFrames, windowState, inOutFrame) ->
+ inOutFrame.set(windowState.getFrameLw()));
+
mDisplayContent.setInsetProvider(ITYPE_BOTTOM_GESTURES, win,
(displayFrames, windowState, inOutFrame) -> {
inOutFrame.top -= mBottomGestureAdditionalInset;
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 2bb58dd..d540179 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -34,6 +34,7 @@
import android.view.InsetsSource;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
+import android.view.InsetsState.InternalInsetsType;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
@@ -61,6 +62,8 @@
private @Nullable ControlAdapter mAdapter;
private TriConsumer<DisplayFrames, WindowState, Rect> mFrameProvider;
+ private TriConsumer<DisplayFrames, WindowState, Rect> mImeFrameProvider;
+ private final Rect mImeOverrideFrame = new Rect();
/** The visibility override from the current controlling window. */
private boolean mClientVisible;
@@ -111,9 +114,12 @@
* @param win The window that links to this source.
* @param frameProvider Based on display frame state and the window, calculates the resulting
* frame that should be reported to clients.
+ * @param imeFrameProvider Based on display frame state and the window, calculates the resulting
+ * frame that should be reported to IME.
*/
void setWindow(@Nullable WindowState win,
- @Nullable TriConsumer<DisplayFrames, WindowState, Rect> frameProvider) {
+ @Nullable TriConsumer<DisplayFrames, WindowState, Rect> frameProvider,
+ @Nullable TriConsumer<DisplayFrames, WindowState, Rect> imeFrameProvider) {
if (mWin != null) {
if (mControllable) {
mWin.setControllableInsetProvider(null);
@@ -126,6 +132,7 @@
}
mWin = win;
mFrameProvider = frameProvider;
+ mImeFrameProvider = imeFrameProvider;
if (win == null) {
setServerVisible(false);
mSource.setFrame(new Rect());
@@ -162,6 +169,12 @@
}
mSource.setFrame(mTmpRect);
+ if (mImeFrameProvider != null) {
+ mImeOverrideFrame.set(mWin.getFrameLw());
+ mImeFrameProvider.accept(mWin.getDisplayContent().mDisplayFrames, mWin,
+ mImeOverrideFrame);
+ }
+
if (mWin.mGivenVisibleInsets.left != 0 || mWin.mGivenVisibleInsets.top != 0
|| mWin.mGivenVisibleInsets.right != 0 || mWin.mGivenVisibleInsets.bottom != 0) {
mTmpRect.set(mWin.getFrameLw());
@@ -303,6 +316,21 @@
return sNewInsetsMode == NEW_INSETS_MODE_NONE || mClientVisible;
}
+ /**
+ * @return Whether this provider uses a different frame to dispatch to the IME.
+ */
+ boolean overridesImeFrame() {
+ return mImeFrameProvider != null;
+ }
+
+ /**
+ * @return Rect to dispatch to the IME as frame. Only valid if {@link #overridesImeFrame()}
+ * returns {@code true}.
+ */
+ Rect getImeOverrideFrame() {
+ return mImeOverrideFrame;
+ }
+
private class ControlAdapter implements AnimationAdapter {
private SurfaceControl mCapturedLeash;
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index b2234d1..3e698da 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -88,6 +88,20 @@
state.removeSource(ITYPE_IME);
state.removeSource(ITYPE_STATUS_BAR);
}
+
+ // IME needs different frames for certain cases (e.g. navigation bar in gesture nav).
+ if (type == ITYPE_IME) {
+ for (int i = mProviders.size() - 1; i >= 0; i--) {
+ InsetsSourceProvider otherProvider = mProviders.valueAt(i);
+ if (otherProvider.overridesImeFrame()) {
+ InsetsSource override =
+ new InsetsSource(state.getSource(otherProvider.getSource().getType()));
+ override.setFrame(otherProvider.getImeOverrideFrame());
+ state.addSource(override);
+ }
+ }
+ }
+
return state;
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 874a25e..aab6b510 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -196,7 +196,6 @@
import android.util.DisplayMetrics;
import android.util.MergedConfiguration;
import android.util.Slog;
-import android.util.StatsLog;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
import android.view.Display;
@@ -227,6 +226,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.policy.KeyInterceptionInfo;
+import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.ToBooleanFunction;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.protolog.common.ProtoLog;
@@ -3154,7 +3154,7 @@
final int requested = mLastRequestedExclusionHeight[side];
final int granted = mLastGrantedExclusionHeight[side];
- StatsLog.write(StatsLog.EXCLUSION_RECT_STATE_CHANGED,
+ FrameworkStatsLog.write(FrameworkStatsLog.EXCLUSION_RECT_STATE_CHANGED,
mAttrs.packageName, requested, requested - granted /* rejected */,
side + 1 /* Sides are 1-indexed in atoms.proto */,
(getConfiguration().orientation == ORIENTATION_LANDSCAPE),
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/AppForegroundHelperTest.java b/services/tests/mockingservicestests/src/com/android/server/location/AppForegroundHelperTest.java
new file mode 100644
index 0000000..38ec4ce
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/location/AppForegroundHelperTest.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.location;
+
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class AppForegroundHelperTest {
+
+ private static final long TIMEOUT_MS = 5000;
+
+ @Mock private Context mContext;
+ @Mock private ActivityManager mActivityManager;
+
+ private List<ActivityManager.OnUidImportanceListener> mListeners = new ArrayList<>();
+
+ private AppForegroundHelper mHelper;
+
+ @Before
+ public void setUp() {
+ initMocks(this);
+
+ doReturn(mActivityManager).when(mContext).getSystemService(ActivityManager.class);
+ doAnswer(invocation -> {
+ mListeners.add(invocation.getArgument(0));
+ return null;
+ }).when(mActivityManager).addOnUidImportanceListener(any(
+ ActivityManager.OnUidImportanceListener.class), eq(IMPORTANCE_FOREGROUND_SERVICE));
+
+ mHelper = new AppForegroundHelper(mContext);
+ mHelper.onSystemReady();
+ }
+
+ private void setImportance(int uid, int importance) {
+ doReturn(importance).when(mActivityManager).getUidImportance(uid);
+ for (ActivityManager.OnUidImportanceListener listener : mListeners) {
+ listener.onUidImportance(uid, importance);
+ }
+ }
+
+ @Test
+ public void testListeners() {
+ AppForegroundHelper.AppForegroundListener listener = mock(
+ AppForegroundHelper.AppForegroundListener.class);
+ mHelper.addListener(listener);
+
+ setImportance(0, IMPORTANCE_FOREGROUND);
+ verify(listener, timeout(TIMEOUT_MS)).onAppForegroundChanged(0, true);
+
+ setImportance(1, IMPORTANCE_FOREGROUND_SERVICE);
+ verify(listener, timeout(TIMEOUT_MS)).onAppForegroundChanged(1, true);
+
+ setImportance(2, IMPORTANCE_VISIBLE);
+ verify(listener, timeout(TIMEOUT_MS)).onAppForegroundChanged(2, false);
+ }
+
+ @Test
+ public void testIsAppForeground() {
+ setImportance(0, IMPORTANCE_FOREGROUND);
+ assertThat(mHelper.isAppForeground(0)).isEqualTo(true);
+
+ setImportance(0, IMPORTANCE_FOREGROUND_SERVICE);
+ assertThat(mHelper.isAppForeground(0)).isEqualTo(true);
+
+ setImportance(0, IMPORTANCE_VISIBLE);
+ assertThat(mHelper.isAppForeground(0)).isEqualTo(false);
+ }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/UserInfoStoreTest.java b/services/tests/mockingservicestests/src/com/android/server/location/UserInfoHelperTest.java
similarity index 73%
rename from services/tests/mockingservicestests/src/com/android/server/location/UserInfoStoreTest.java
rename to services/tests/mockingservicestests/src/com/android/server/location/UserInfoHelperTest.java
index 06fb102..389fdf9 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/UserInfoStoreTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/UserInfoHelperTest.java
@@ -57,7 +57,7 @@
@Presubmit
@SmallTest
@RunWith(AndroidJUnit4.class)
-public class UserInfoStoreTest {
+public class UserInfoHelperTest {
private static final int USER1_ID = 1;
private static final int USER1_MANAGED_ID = 11;
@@ -72,7 +72,7 @@
private StaticMockitoSession mMockingSession;
private List<BroadcastReceiver> mBroadcastReceivers = new ArrayList<>();
- private UserInfoStore mStore;
+ private UserInfoHelper mHelper;
@Before
public void setUp() {
@@ -97,8 +97,8 @@
doReturn(USER1_ID).when(ActivityManager::getCurrentUser);
- mStore = new UserInfoStore(mContext);
- mStore.onSystemReady();
+ mHelper = new UserInfoHelper(mContext);
+ mHelper.onSystemReady();
}
@After
@@ -119,8 +119,9 @@
@Test
public void testListeners() {
- UserInfoStore.UserChangedListener listener = mock(UserInfoStore.UserChangedListener.class);
- mStore.addListener(listener);
+ UserInfoHelper.UserChangedListener listener = mock(
+ UserInfoHelper.UserChangedListener.class);
+ mHelper.addListener(listener);
switchUser(USER1_ID);
verify(listener, never()).onUserChanged(anyInt(), anyInt());
@@ -134,44 +135,44 @@
@Test
public void testCurrentUser() {
- assertThat(mStore.getCurrentUserId()).isEqualTo(USER1_ID);
+ assertThat(mHelper.getCurrentUserId()).isEqualTo(USER1_ID);
switchUser(USER2_ID);
- assertThat(mStore.getCurrentUserId()).isEqualTo(USER2_ID);
+ assertThat(mHelper.getCurrentUserId()).isEqualTo(USER2_ID);
switchUser(USER1_ID);
- assertThat(mStore.getCurrentUserId()).isEqualTo(USER1_ID);
+ assertThat(mHelper.getCurrentUserId()).isEqualTo(USER1_ID);
}
@Test
public void testIsCurrentUserOrProfile() {
- assertThat(mStore.isCurrentUserOrProfile(USER1_ID)).isTrue();
- assertThat(mStore.isCurrentUserOrProfile(USER1_MANAGED_ID)).isTrue();
- assertThat(mStore.isCurrentUserOrProfile(USER2_ID)).isFalse();
- assertThat(mStore.isCurrentUserOrProfile(USER2_MANAGED_ID)).isFalse();
+ assertThat(mHelper.isCurrentUserOrProfile(USER1_ID)).isTrue();
+ assertThat(mHelper.isCurrentUserOrProfile(USER1_MANAGED_ID)).isTrue();
+ assertThat(mHelper.isCurrentUserOrProfile(USER2_ID)).isFalse();
+ assertThat(mHelper.isCurrentUserOrProfile(USER2_MANAGED_ID)).isFalse();
switchUser(USER2_ID);
- assertThat(mStore.isCurrentUserOrProfile(USER1_ID)).isFalse();
- assertThat(mStore.isCurrentUserOrProfile(USER2_ID)).isTrue();
- assertThat(mStore.isCurrentUserOrProfile(USER1_MANAGED_ID)).isFalse();
- assertThat(mStore.isCurrentUserOrProfile(USER2_MANAGED_ID)).isTrue();
+ assertThat(mHelper.isCurrentUserOrProfile(USER1_ID)).isFalse();
+ assertThat(mHelper.isCurrentUserOrProfile(USER2_ID)).isTrue();
+ assertThat(mHelper.isCurrentUserOrProfile(USER1_MANAGED_ID)).isFalse();
+ assertThat(mHelper.isCurrentUserOrProfile(USER2_MANAGED_ID)).isTrue();
}
@Test
public void testGetParentUserId() {
- assertThat(mStore.getParentUserId(USER1_ID)).isEqualTo(USER1_ID);
- assertThat(mStore.getParentUserId(USER1_MANAGED_ID)).isEqualTo(USER1_ID);
- assertThat(mStore.getParentUserId(USER2_ID)).isEqualTo(USER2_ID);
- assertThat(mStore.getParentUserId(USER2_MANAGED_ID)).isEqualTo(USER2_ID);
+ assertThat(mHelper.getParentUserId(USER1_ID)).isEqualTo(USER1_ID);
+ assertThat(mHelper.getParentUserId(USER1_MANAGED_ID)).isEqualTo(USER1_ID);
+ assertThat(mHelper.getParentUserId(USER2_ID)).isEqualTo(USER2_ID);
+ assertThat(mHelper.getParentUserId(USER2_MANAGED_ID)).isEqualTo(USER2_ID);
switchUser(USER2_ID);
- assertThat(mStore.getParentUserId(USER1_ID)).isEqualTo(USER1_ID);
- assertThat(mStore.getParentUserId(USER2_ID)).isEqualTo(USER2_ID);
- assertThat(mStore.getParentUserId(USER1_MANAGED_ID)).isEqualTo(USER1_ID);
- assertThat(mStore.getParentUserId(USER2_MANAGED_ID)).isEqualTo(USER2_ID);
+ assertThat(mHelper.getParentUserId(USER1_ID)).isEqualTo(USER1_ID);
+ assertThat(mHelper.getParentUserId(USER2_ID)).isEqualTo(USER2_ID);
+ assertThat(mHelper.getParentUserId(USER1_MANAGED_ID)).isEqualTo(USER1_ID);
+ assertThat(mHelper.getParentUserId(USER2_MANAGED_ID)).isEqualTo(USER2_ID);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/location/gnss/GnssManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/location/gnss/GnssManagerServiceTest.java
index f262733..f16cf35 100644
--- a/services/tests/servicestests/src/com/android/server/location/gnss/GnssManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/location/gnss/GnssManagerServiceTest.java
@@ -24,6 +24,7 @@
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -31,7 +32,6 @@
import static org.testng.Assert.assertThrows;
import android.Manifest;
-import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -46,13 +46,15 @@
import android.location.IGnssStatusListener;
import android.location.INetInitiatedListener;
import android.location.Location;
+import android.location.LocationManagerInternal;
import android.os.Handler;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Message;
import android.os.RemoteException;
-import com.android.server.LocationManagerService;
+import com.android.server.LocalServices;
+import com.android.server.location.AppForegroundHelper;
import com.android.server.location.GnssBatchingProvider;
import com.android.server.location.GnssCapabilitiesProvider;
import com.android.server.location.GnssLocationProvider;
@@ -63,7 +65,9 @@
import com.android.server.location.GnssNavigationMessageProvider.GnssNavigationMessageProviderNative;
import com.android.server.location.GnssStatusListenerHelper;
import com.android.server.location.LocationUsageLogger;
+import com.android.server.location.SettingsHelper;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.AdditionalMatchers;
@@ -93,18 +97,20 @@
@Mock
private GnssMeasurementCorrectionsProvider mMockGnssMeasurementCorrectionsProvider;
@Mock
- private INetInitiatedListener mMockNetInitiatedListener;
+ private INetInitiatedListener mNetInitiatedListener;
private GnssMeasurementsProvider mTestGnssMeasurementsProvider;
private GnssStatusListenerHelper mTestGnssStatusProvider;
private GnssNavigationMessageProvider mTestGnssNavigationMessageProvider;
// Managers and services
@Mock
- private AppOpsManager mMockAppOpsManager;
+ private AppOpsManager mAppOpsManager;
@Mock
- private ActivityManager mMockActivityManager;
+ private SettingsHelper mSettingsHelper;
@Mock
- private LocationManagerService mMockLocationManagerService;
+ private AppForegroundHelper mAppForegroundHelper;
+ @Mock
+ private LocationManagerInternal mLocationManagerInternal;
// Context and handler
@Mock
@@ -113,25 +119,23 @@
private Context mMockContext;
// Class under test
- private com.android.server.location.gnss.GnssManagerService mGnssManagerService;
+ private GnssManagerService mGnssManagerService;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
GnssLocationProvider.setIsSupportedForTest(true);
- // Set up mock context
when(mMockContext.getSystemServiceName(AppOpsManager.class)).thenReturn(
Context.APP_OPS_SERVICE);
- when(mMockContext.getSystemServiceName(ActivityManager.class)).thenReturn(
- Context.ACTIVITY_SERVICE);
when(mMockContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(
- mMockAppOpsManager);
- when(mMockContext.getSystemService(
- eq(Context.ACTIVITY_SERVICE))).thenReturn(
- mMockActivityManager);
+ mAppOpsManager);
enableLocationPermissions();
+ when(mAppForegroundHelper.isAppForeground(anyInt())).thenReturn(true);
+
+ LocalServices.addService(LocationManagerInternal.class, mLocationManagerInternal);
+
// Mock Handler will execute posted runnables immediately
when(mMockHandler.sendMessageAtTime(any(Message.class), anyLong())).thenAnswer(
(InvocationOnMock invocation) -> {
@@ -164,15 +168,22 @@
when(mMockGnssLocationProvider.getGnssNavigationMessageProvider()).thenReturn(
mTestGnssNavigationMessageProvider);
when(mMockGnssLocationProvider.getNetInitiatedListener()).thenReturn(
- mMockNetInitiatedListener);
+ mNetInitiatedListener);
// Setup GnssBatching provider
when(mMockGnssBatchingProvider.start(anyLong(), anyBoolean())).thenReturn(true);
when(mMockGnssBatchingProvider.stop()).thenReturn(true);
// Create GnssManagerService
- mGnssManagerService = new GnssManagerService(mMockLocationManagerService, mMockContext,
- mMockGnssLocationProvider, new LocationUsageLogger());
+ mGnssManagerService = new GnssManagerService(mMockContext, mSettingsHelper,
+ mAppForegroundHelper, new LocationUsageLogger(),
+ mMockGnssLocationProvider);
+ mGnssManagerService.onSystemReady();
+ }
+
+ @After
+ public void tearDown() {
+ LocalServices.removeServiceForTest(LocationManagerInternal.class);
}
private void overrideAsBinder(IInterface mockListener) {
@@ -225,7 +236,7 @@
PackageManager.PERMISSION_GRANTED);
// AppOpsManager will return true if OP_FINE_LOCATION is checked
- when(mMockAppOpsManager.checkOp(anyInt(), anyInt(), anyString())).thenAnswer(
+ when(mAppOpsManager.checkOp(anyInt(), anyInt(), anyString())).thenAnswer(
(InvocationOnMock invocation) -> {
int code = (int) (invocation.getArguments()[0]);
if (code == AppOpsManager.OP_FINE_LOCATION) {
@@ -237,11 +248,11 @@
private void disableLocationPermissions() {
Mockito.doThrow(new SecurityException()).when(
- mMockContext).enforceCallingPermission(anyString(), anyString());
+ mMockContext).enforceCallingPermission(anyString(), nullable(String.class));
Mockito.doThrow(new SecurityException()).when(
mMockContext).checkPermission(anyString(), anyInt(), anyInt());
- when(mMockAppOpsManager.checkOp(anyInt(), anyInt(),
+ when(mAppOpsManager.checkOp(anyInt(), anyInt(),
anyString())).thenReturn(AppOpsManager.MODE_ERRORED);
}
@@ -733,14 +744,12 @@
@Test
public void sendNiResponseWithPermissionsTest() throws RemoteException {
- when(mMockNetInitiatedListener.sendNiResponse(anyInt(), anyInt())).thenReturn(true);
-
int notifId = 0;
int userResponse = 0;
enableLocationPermissions();
- assertThat(mGnssManagerService.sendNiResponse(notifId, userResponse)).isEqualTo(true);
+ mGnssManagerService.sendNiResponse(notifId, userResponse);
- verify(mMockNetInitiatedListener, times(1)).sendNiResponse(notifId, userResponse);
+ verify(mNetInitiatedListener, times(1)).sendNiResponse(notifId, userResponse);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/rollback/AppDataRollbackHelperTest.java b/services/tests/servicestests/src/com/android/server/rollback/AppDataRollbackHelperTest.java
index f871203..3ceaac2 100644
--- a/services/tests/servicestests/src/com/android/server/rollback/AppDataRollbackHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/rollback/AppDataRollbackHelperTest.java
@@ -27,6 +27,7 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
+import static org.mockito.MockitoAnnotations.initMocks;
import android.content.pm.VersionedPackage;
import android.content.rollback.PackageRollbackInfo;
@@ -34,12 +35,15 @@
import android.util.IntArray;
import android.util.SparseLongArray;
+import com.android.server.pm.ApexManager;
import com.android.server.pm.Installer;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.InOrder;
+import org.mockito.Mock;
import org.mockito.Mockito;
import java.io.File;
@@ -48,10 +52,17 @@
@RunWith(JUnit4.class)
public class AppDataRollbackHelperTest {
+ @Mock private ApexManager mApexManager;
+
+ @Before
+ public void setUp() {
+ initMocks(this);
+ }
+
@Test
public void testSnapshotAppData() throws Exception {
Installer installer = mock(Installer.class);
- AppDataRollbackHelper helper = spy(new AppDataRollbackHelper(installer));
+ AppDataRollbackHelper helper = spy(new AppDataRollbackHelper(installer, mApexManager));
// All users are unlocked so we should snapshot data for them.
doReturn(true).when(helper).isUserCredentialLocked(eq(10));
@@ -114,7 +125,7 @@
@Test
public void testRestoreAppDataSnapshot_pendingBackupForUser() throws Exception {
Installer installer = mock(Installer.class);
- AppDataRollbackHelper helper = spy(new AppDataRollbackHelper(installer));
+ AppDataRollbackHelper helper = spy(new AppDataRollbackHelper(installer, mApexManager));
PackageRollbackInfo info = createPackageRollbackInfo("com.foo");
IntArray pendingBackups = info.getPendingBackups();
@@ -139,7 +150,7 @@
@Test
public void testRestoreAppDataSnapshot_availableBackupForLockedUser() throws Exception {
Installer installer = mock(Installer.class);
- AppDataRollbackHelper helper = spy(new AppDataRollbackHelper(installer));
+ AppDataRollbackHelper helper = spy(new AppDataRollbackHelper(installer, mApexManager));
doReturn(true).when(helper).isUserCredentialLocked(eq(10));
PackageRollbackInfo info = createPackageRollbackInfo("com.foo");
@@ -163,7 +174,7 @@
@Test
public void testRestoreAppDataSnapshot_availableBackupForUnlockedUser() throws Exception {
Installer installer = mock(Installer.class);
- AppDataRollbackHelper helper = spy(new AppDataRollbackHelper(installer));
+ AppDataRollbackHelper helper = spy(new AppDataRollbackHelper(installer, mApexManager));
doReturn(false).when(helper).isUserCredentialLocked(eq(10));
PackageRollbackInfo info = createPackageRollbackInfo("com.foo");
@@ -184,7 +195,7 @@
@Test
public void destroyAppData() throws Exception {
Installer installer = mock(Installer.class);
- AppDataRollbackHelper helper = new AppDataRollbackHelper(installer);
+ AppDataRollbackHelper helper = new AppDataRollbackHelper(installer, mApexManager);
PackageRollbackInfo info = createPackageRollbackInfo("com.foo.bar");
info.putCeSnapshotInode(11, 239L);
@@ -206,7 +217,7 @@
@Test
public void commitPendingBackupAndRestoreForUser() throws Exception {
Installer installer = mock(Installer.class);
- AppDataRollbackHelper helper = new AppDataRollbackHelper(installer);
+ AppDataRollbackHelper helper = new AppDataRollbackHelper(installer, mApexManager);
when(installer.snapshotAppData(anyString(), anyInt(), anyInt(), anyInt())).thenReturn(53L);
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
index d819b1a..7ffdd7c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
@@ -57,7 +57,7 @@
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
statusBar.getFrameLw().set(0, 0, 500, 100);
statusBar.mHasSurface = true;
- mProvider.setWindow(statusBar, null);
+ mProvider.setWindow(statusBar, null, null);
mProvider.onPostLayout();
assertEquals(new Rect(0, 0, 500, 100), mProvider.getSource().getFrame());
assertEquals(Insets.of(0, 100, 0, 0),
@@ -74,7 +74,7 @@
ime.getGivenContentInsetsLw().set(0, 0, 0, 60);
ime.getGivenVisibleInsetsLw().set(0, 0, 0, 75);
ime.mHasSurface = true;
- mProvider.setWindow(ime, null);
+ mProvider.setWindow(ime, null, null);
mProvider.onPostLayout();
assertEquals(new Rect(0, 0, 500, 40), mProvider.getSource().getFrame());
assertEquals(new Rect(0, 0, 500, 25), mProvider.getSource().getVisibleFrame());
@@ -89,7 +89,7 @@
public void testPostLayout_invisible() {
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
statusBar.getFrameLw().set(0, 0, 500, 100);
- mProvider.setWindow(statusBar, null);
+ mProvider.setWindow(statusBar, null, null);
mProvider.onPostLayout();
assertEquals(Insets.NONE, mProvider.getSource().calculateInsets(new Rect(0, 0, 500, 500),
false /* ignoreVisibility */));
@@ -102,7 +102,7 @@
mProvider.setWindow(statusBar,
(displayFrames, windowState, rect) -> {
rect.set(10, 10, 20, 20);
- });
+ }, null);
mProvider.onPostLayout();
assertEquals(new Rect(10, 10, 20, 20), mProvider.getSource().getFrame());
}
@@ -112,7 +112,7 @@
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
statusBar.getFrameLw().set(0, 0, 500, 100);
- mProvider.setWindow(statusBar, null);
+ mProvider.setWindow(statusBar, null, null);
mProvider.updateControlForTarget(target, false /* force */);
assertNotNull(mProvider.getControl(target));
mProvider.updateControlForTarget(null, false /* force */);
@@ -124,7 +124,7 @@
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
statusBar.getFrameLw().set(0, 0, 500, 100);
- mProvider.setWindow(statusBar, null);
+ mProvider.setWindow(statusBar, null, null);
mProvider.updateControlForFakeTarget(target);
assertNotNull(mProvider.getControl(target));
assertNull(mProvider.getControl(target).getLeash());
@@ -137,7 +137,7 @@
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
statusBar.getFrameLw().set(0, 0, 500, 100);
- mProvider.setWindow(statusBar, null);
+ mProvider.setWindow(statusBar, null, null);
mProvider.updateControlForTarget(target, false /* force */);
InsetsState state = new InsetsState();
state.getSource(ITYPE_STATUS_BAR).setVisible(false);
@@ -150,7 +150,7 @@
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
statusBar.getFrameLw().set(0, 0, 500, 100);
- mProvider.setWindow(statusBar, null);
+ mProvider.setWindow(statusBar, null, null);
InsetsState state = new InsetsState();
state.getSource(ITYPE_STATUS_BAR).setVisible(false);
mProvider.onInsetsModified(target, state.getSource(ITYPE_STATUS_BAR));
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
index d13baec..39cdd2c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
@@ -21,26 +21,26 @@
import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import android.view.InsetsSource;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
import android.view.test.InsetsModeSession;
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.SmallTest;
-
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
+import androidx.test.filters.FlakyTest;
+import androidx.test.filters.SmallTest;
+
@SmallTest
@FlakyTest(detail = "Promote to pre-submit once confirmed stable.")
@Presubmit
@@ -65,7 +65,7 @@
public void testStripForDispatch_notOwn() {
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
- getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null);
+ getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null, null);
statusBar.setControllableInsetProvider(getController().getSourceProvider(ITYPE_STATUS_BAR));
assertNotNull(getController().getInsetsForDispatch(app).getSource(ITYPE_STATUS_BAR));
}
@@ -74,7 +74,7 @@
public void testStripForDispatch_own() {
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
mDisplayContent.getInsetsStateController().getSourceProvider(ITYPE_STATUS_BAR)
- .setWindow(statusBar, null);
+ .setWindow(statusBar, null, null);
statusBar.setControllableInsetProvider(getController().getSourceProvider(ITYPE_STATUS_BAR));
final InsetsState state = getController().getInsetsForDispatch(statusBar);
for (int i = state.getSourcesCount() - 1; i >= 0; i--) {
@@ -88,19 +88,36 @@
final WindowState navBar = createWindow(null, TYPE_APPLICATION, "navBar");
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
final WindowState ime = createWindow(null, TYPE_APPLICATION, "ime");
- getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null);
- getController().getSourceProvider(ITYPE_NAVIGATION_BAR).setWindow(navBar, null);
- getController().getSourceProvider(ITYPE_IME).setWindow(ime, null);
+ getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null, null);
+ getController().getSourceProvider(ITYPE_NAVIGATION_BAR).setWindow(navBar, null, null);
+ getController().getSourceProvider(ITYPE_IME).setWindow(ime, null, null);
assertEquals(0, getController().getInsetsForDispatch(navBar).getSourcesCount());
}
@Test
+ public void testImeForDispatch() {
+ final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
+ final WindowState ime = createWindow(null, TYPE_APPLICATION, "ime");
+ InsetsSourceProvider statusBarProvider =
+ getController().getSourceProvider(ITYPE_STATUS_BAR);
+ statusBarProvider.setWindow(statusBar, null, ((displayFrames, windowState, rect) ->
+ rect.set(0, 1, 2, 3)));
+ getController().getSourceProvider(ITYPE_IME).setWindow(ime, null, null);
+ statusBar.setControllableInsetProvider(statusBarProvider);
+
+ statusBarProvider.onPostLayout();
+
+ final InsetsState state = getController().getInsetsForDispatch(ime);
+ assertEquals(new Rect(0, 1, 2, 3), state.getSource(ITYPE_STATUS_BAR).getFrame());
+ }
+
+ @Test
public void testBarControllingWinChanged() {
final WindowState navBar = createWindow(null, TYPE_APPLICATION, "navBar");
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
- getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null);
- getController().getSourceProvider(ITYPE_NAVIGATION_BAR).setWindow(navBar, null);
+ getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null, null);
+ getController().getSourceProvider(ITYPE_NAVIGATION_BAR).setWindow(navBar, null, null);
getController().onBarControlTargetChanged(app, null, app, null);
InsetsSourceControl[] controls = getController().getControlsForDispatch(app);
assertEquals(2, controls.length);
@@ -110,7 +127,7 @@
public void testControlRevoked() {
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
- getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null);
+ getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null, null);
getController().onBarControlTargetChanged(app, null, null, null);
assertNotNull(getController().getControlsForDispatch(app));
getController().onBarControlTargetChanged(null, null, null, null);
@@ -122,7 +139,7 @@
public void testControlRevoked_animation() {
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
- getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null);
+ getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null, null);
getController().onBarControlTargetChanged(app, null, null, null);
assertNotNull(getController().getControlsForDispatch(app));
statusBar.cancelAnimation();
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 186ff6b..2c68cc7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -425,7 +425,7 @@
statusBar.mHasSurface = true;
assertTrue(statusBar.isVisible());
mDisplayContent.getInsetsStateController().getSourceProvider(ITYPE_STATUS_BAR)
- .setWindow(statusBar, null /* frameProvider */);
+ .setWindow(statusBar, null /* frameProvider */, null /* imeFrameProvider */);
mDisplayContent.getInsetsStateController().onBarControlTargetChanged(
app, null /* fakeTopControlling */, app, null /* fakeNavControlling */);
final InsetsSource source = new InsetsSource(ITYPE_STATUS_BAR);
diff --git a/telephony/java/android/telephony/CallForwardingInfo.java b/telephony/java/android/telephony/CallForwardingInfo.java
index 33ad5e8..1dd7539 100644
--- a/telephony/java/android/telephony/CallForwardingInfo.java
+++ b/telephony/java/android/telephony/CallForwardingInfo.java
@@ -15,7 +15,6 @@
*/
package android.telephony;
-
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
@@ -25,6 +24,8 @@
import android.telephony.Annotation.CallForwardingReason;
import android.telephony.Annotation.CallForwardingStatus;
+import com.android.telephony.Rlog;
+
import java.util.Objects;
/**
diff --git a/telephony/java/android/telephony/CellIdentity.java b/telephony/java/android/telephony/CellIdentity.java
index 3f0aeb5..0c2f1f3 100644
--- a/telephony/java/android/telephony/CellIdentity.java
+++ b/telephony/java/android/telephony/CellIdentity.java
@@ -69,8 +69,8 @@
protected String mAlphaShort;
/** @hide */
- protected CellIdentity(String tag, int type, String mcc, String mnc, String alphal,
- String alphas) {
+ protected CellIdentity(@Nullable String tag, int type, @Nullable String mcc,
+ @Nullable String mnc, @Nullable String alphal, @Nullable String alphas) {
mTag = tag;
mType = type;
diff --git a/telephony/java/android/telephony/CellIdentityCdma.java b/telephony/java/android/telephony/CellIdentityCdma.java
index 1a6bf33..e220b07 100644
--- a/telephony/java/android/telephony/CellIdentityCdma.java
+++ b/telephony/java/android/telephony/CellIdentityCdma.java
@@ -17,6 +17,7 @@
package android.telephony;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.os.Parcel;
import android.telephony.cdma.CdmaCellLocation;
@@ -90,8 +91,8 @@
*
* @hide
*/
- public CellIdentityCdma(
- int nid, int sid, int bid, int lon, int lat, String alphal, String alphas) {
+ public CellIdentityCdma(int nid, int sid, int bid, int lon, int lat,
+ @Nullable String alphal, @Nullable String alphas) {
super(TAG, CellInfo.TYPE_CDMA, null, null, alphal, alphas);
mNetworkId = inRangeOrUnavailable(nid, 0, NETWORK_ID_MAX);
mSystemId = inRangeOrUnavailable(sid, 0, SYSTEM_ID_MAX);
@@ -108,22 +109,22 @@
}
/** @hide */
- public CellIdentityCdma(android.hardware.radio.V1_0.CellIdentityCdma cid) {
+ public CellIdentityCdma(@NonNull android.hardware.radio.V1_0.CellIdentityCdma cid) {
this(cid.networkId, cid.systemId, cid.baseStationId, cid.longitude, cid.latitude, "", "");
}
/** @hide */
- public CellIdentityCdma(android.hardware.radio.V1_2.CellIdentityCdma cid) {
+ public CellIdentityCdma(@NonNull android.hardware.radio.V1_2.CellIdentityCdma cid) {
this(cid.base.networkId, cid.base.systemId, cid.base.baseStationId, cid.base.longitude,
cid.base.latitude, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort);
}
- private CellIdentityCdma(CellIdentityCdma cid) {
+ private CellIdentityCdma(@NonNull CellIdentityCdma cid) {
this(cid.mNetworkId, cid.mSystemId, cid.mBasestationId, cid.mLongitude, cid.mLatitude,
cid.mAlphaLong, cid.mAlphaShort);
}
- CellIdentityCdma copy() {
+ @NonNull CellIdentityCdma copy() {
return new CellIdentityCdma(this);
}
diff --git a/telephony/java/android/telephony/CellIdentityGsm.java b/telephony/java/android/telephony/CellIdentityGsm.java
index dc73cbf..9f2537c 100644
--- a/telephony/java/android/telephony/CellIdentityGsm.java
+++ b/telephony/java/android/telephony/CellIdentityGsm.java
@@ -23,6 +23,7 @@
import android.telephony.gsm.GsmCellLocation;
import android.text.TextUtils;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -78,26 +79,31 @@
*
* @hide
*/
- public CellIdentityGsm(int lac, int cid, int arfcn, int bsic, String mccStr,
- String mncStr, String alphal, String alphas,
- List<String> additionalPlmns) {
+ public CellIdentityGsm(int lac, int cid, int arfcn, int bsic, @Nullable String mccStr,
+ @Nullable String mncStr, @Nullable String alphal, @Nullable String alphas,
+ @NonNull List<String> additionalPlmns) {
super(TAG, CellInfo.TYPE_GSM, mccStr, mncStr, alphal, alphas);
mLac = inRangeOrUnavailable(lac, 0, MAX_LAC);
mCid = inRangeOrUnavailable(cid, 0, MAX_CID);
mArfcn = inRangeOrUnavailable(arfcn, 0, MAX_ARFCN);
mBsic = inRangeOrUnavailable(bsic, 0, MAX_BSIC);
- mAdditionalPlmns = additionalPlmns;
+ mAdditionalPlmns = new ArrayList<>(additionalPlmns.size());
+ for (String plmn : additionalPlmns) {
+ if (isValidPlmn(plmn)) {
+ mAdditionalPlmns.add(plmn);
+ }
+ }
}
/** @hide */
- public CellIdentityGsm(android.hardware.radio.V1_0.CellIdentityGsm cid) {
+ public CellIdentityGsm(@NonNull android.hardware.radio.V1_0.CellIdentityGsm cid) {
this(cid.lac, cid.cid, cid.arfcn,
cid.bsic == (byte) 0xFF ? CellInfo.UNAVAILABLE : cid.bsic,
cid.mcc, cid.mnc, "", "", Collections.emptyList());
}
/** @hide */
- public CellIdentityGsm(android.hardware.radio.V1_2.CellIdentityGsm cid) {
+ public CellIdentityGsm(@NonNull android.hardware.radio.V1_2.CellIdentityGsm cid) {
this(cid.base.lac, cid.base.cid, cid.base.arfcn,
cid.base.bsic == (byte) 0xFF ? CellInfo.UNAVAILABLE : cid.base.bsic, cid.base.mcc,
cid.base.mnc, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort,
@@ -105,7 +111,7 @@
}
/** @hide */
- public CellIdentityGsm(android.hardware.radio.V1_5.CellIdentityGsm cid) {
+ public CellIdentityGsm(@NonNull android.hardware.radio.V1_5.CellIdentityGsm cid) {
this(cid.base.base.lac, cid.base.base.cid, cid.base.base.arfcn,
cid.base.base.bsic == (byte) 0xFF ? CellInfo.UNAVAILABLE
: cid.base.base.bsic, cid.base.base.mcc,
@@ -113,12 +119,12 @@
cid.base.operatorNames.alphaShort, cid.additionalPlmns);
}
- private CellIdentityGsm(CellIdentityGsm cid) {
+ private CellIdentityGsm(@NonNull CellIdentityGsm cid) {
this(cid.mLac, cid.mCid, cid.mArfcn, cid.mBsic, cid.mMccStr,
cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort, cid.mAdditionalPlmns);
}
- CellIdentityGsm copy() {
+ @NonNull CellIdentityGsm copy() {
return new CellIdentityGsm(this);
}
diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java
index cf8fe6a..a194ae3 100644
--- a/telephony/java/android/telephony/CellIdentityLte.java
+++ b/telephony/java/android/telephony/CellIdentityLte.java
@@ -24,6 +24,7 @@
import android.telephony.gsm.GsmCellLocation;
import android.text.TextUtils;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -104,34 +105,40 @@
*
* @hide
*/
- public CellIdentityLte(int ci, int pci, int tac, int earfcn, int bandwidth, String mccStr,
- String mncStr, String alphal, String alphas, List<String> additionalPlmns,
- ClosedSubscriberGroupInfo csgInfo) {
+ public CellIdentityLte(int ci, int pci, int tac, int earfcn, int bandwidth,
+ @Nullable String mccStr, @Nullable String mncStr, @Nullable String alphal,
+ @Nullable String alphas, @NonNull List<String> additionalPlmns,
+ @Nullable ClosedSubscriberGroupInfo csgInfo) {
super(TAG, CellInfo.TYPE_LTE, mccStr, mncStr, alphal, alphas);
mCi = inRangeOrUnavailable(ci, 0, MAX_CI);
mPci = inRangeOrUnavailable(pci, 0, MAX_PCI);
mTac = inRangeOrUnavailable(tac, 0, MAX_TAC);
mEarfcn = inRangeOrUnavailable(earfcn, 0, MAX_EARFCN);
mBandwidth = inRangeOrUnavailable(bandwidth, 0, MAX_BANDWIDTH);
- mAdditionalPlmns = additionalPlmns;
+ mAdditionalPlmns = new ArrayList<>(additionalPlmns.size());
+ for (String plmn : additionalPlmns) {
+ if (isValidPlmn(plmn)) {
+ mAdditionalPlmns.add(plmn);
+ }
+ }
mCsgInfo = csgInfo;
}
/** @hide */
- public CellIdentityLte(android.hardware.radio.V1_0.CellIdentityLte cid) {
+ public CellIdentityLte(@NonNull android.hardware.radio.V1_0.CellIdentityLte cid) {
this(cid.ci, cid.pci, cid.tac, cid.earfcn,
CellInfo.UNAVAILABLE, cid.mcc, cid.mnc, "", "", Collections.emptyList(), null);
}
/** @hide */
- public CellIdentityLte(android.hardware.radio.V1_2.CellIdentityLte cid) {
+ public CellIdentityLte(@NonNull android.hardware.radio.V1_2.CellIdentityLte cid) {
this(cid.base.ci, cid.base.pci, cid.base.tac, cid.base.earfcn, cid.bandwidth,
cid.base.mcc, cid.base.mnc, cid.operatorNames.alphaLong,
cid.operatorNames.alphaShort, Collections.emptyList(), null);
}
/** @hide */
- public CellIdentityLte(android.hardware.radio.V1_5.CellIdentityLte cid) {
+ public CellIdentityLte(@NonNull android.hardware.radio.V1_5.CellIdentityLte cid) {
this(cid.base.base.ci, cid.base.base.pci, cid.base.base.tac, cid.base.base.earfcn,
cid.base.bandwidth, cid.base.base.mcc, cid.base.base.mnc,
cid.base.operatorNames.alphaLong, cid.base.operatorNames.alphaShort,
@@ -139,7 +146,7 @@
? new ClosedSubscriberGroupInfo(cid.optionalCsgInfo.csgInfo()) : null);
}
- private CellIdentityLte(CellIdentityLte cid) {
+ private CellIdentityLte(@NonNull CellIdentityLte cid) {
this(cid.mCi, cid.mPci, cid.mTac, cid.mEarfcn, cid.mBandwidth, cid.mMccStr,
cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort, cid.mAdditionalPlmns, cid.mCsgInfo);
}
@@ -152,7 +159,7 @@
mMccStr, mMncStr, mAlphaLong, mAlphaShort, mAdditionalPlmns, null);
}
- CellIdentityLte copy() {
+ @NonNull CellIdentityLte copy() {
return new CellIdentityLte(this);
}
diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java
index d4f181f..a0ef5aa 100644
--- a/telephony/java/android/telephony/CellIdentityNr.java
+++ b/telephony/java/android/telephony/CellIdentityNr.java
@@ -64,26 +64,32 @@
* @hide
*/
public CellIdentityNr(int pci, int tac, int nrArfcn, @NgranBand List<Integer> bands,
- String mccStr, String mncStr, long nci, String alphal, String alphas,
- List<String> additionalPlmns) {
+ @Nullable String mccStr, @Nullable String mncStr, long nci,
+ @Nullable String alphal, @Nullable String alphas,
+ @NonNull List<String> additionalPlmns) {
super(TAG, CellInfo.TYPE_NR, mccStr, mncStr, alphal, alphas);
mPci = inRangeOrUnavailable(pci, 0, MAX_PCI);
mTac = inRangeOrUnavailable(tac, 0, MAX_TAC);
mNrArfcn = inRangeOrUnavailable(nrArfcn, 0, MAX_NRARFCN);
mBands = new ArrayList<>(bands);
mNci = inRangeOrUnavailable(nci, 0, MAX_NCI);
- mAdditionalPlmns = new ArrayList<>(additionalPlmns);
+ mAdditionalPlmns = new ArrayList<>(additionalPlmns.size());
+ for (String plmn : additionalPlmns) {
+ if (isValidPlmn(plmn)) {
+ mAdditionalPlmns.add(plmn);
+ }
+ }
}
/** @hide */
- public CellIdentityNr(android.hardware.radio.V1_4.CellIdentityNr cid) {
+ public CellIdentityNr(@NonNull android.hardware.radio.V1_4.CellIdentityNr cid) {
this(cid.pci, cid.tac, cid.nrarfcn, Collections.emptyList(), cid.mcc, cid.mnc, cid.nci,
cid.operatorNames.alphaLong, cid.operatorNames.alphaShort,
Collections.emptyList());
}
/** @hide */
- public CellIdentityNr(android.hardware.radio.V1_5.CellIdentityNr cid) {
+ public CellIdentityNr(@NonNull android.hardware.radio.V1_5.CellIdentityNr cid) {
this(cid.base.pci, cid.base.tac, cid.base.nrarfcn, cid.bands, cid.base.mcc, cid.base.mnc,
cid.base.nci, cid.base.operatorNames.alphaLong,
cid.base.operatorNames.alphaShort, cid.additionalPlmns);
diff --git a/telephony/java/android/telephony/CellIdentityTdscdma.java b/telephony/java/android/telephony/CellIdentityTdscdma.java
index 2ff351c..531487a 100644
--- a/telephony/java/android/telephony/CellIdentityTdscdma.java
+++ b/telephony/java/android/telephony/CellIdentityTdscdma.java
@@ -21,6 +21,7 @@
import android.os.Parcel;
import android.telephony.gsm.GsmCellLocation;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -82,39 +83,44 @@
*
* @hide
*/
- public CellIdentityTdscdma(String mcc, String mnc, int lac, int cid, int cpid, int uarfcn,
- String alphal, String alphas, @NonNull List<String> additionalPlmns,
- ClosedSubscriberGroupInfo csgInfo) {
+ public CellIdentityTdscdma(@Nullable String mcc, @Nullable String mnc, int lac, int cid,
+ int cpid, int uarfcn, @Nullable String alphal, @Nullable String alphas,
+ @NonNull List<String> additionalPlmns, @Nullable ClosedSubscriberGroupInfo csgInfo) {
super(TAG, CellInfo.TYPE_TDSCDMA, mcc, mnc, alphal, alphas);
mLac = inRangeOrUnavailable(lac, 0, MAX_LAC);
mCid = inRangeOrUnavailable(cid, 0, MAX_CID);
mCpid = inRangeOrUnavailable(cpid, 0, MAX_CPID);
mUarfcn = inRangeOrUnavailable(uarfcn, 0, MAX_UARFCN);
- mAdditionalPlmns = additionalPlmns;
+ mAdditionalPlmns = new ArrayList<>(additionalPlmns.size());
+ for (String plmn : additionalPlmns) {
+ if (isValidPlmn(plmn)) {
+ mAdditionalPlmns.add(plmn);
+ }
+ }
mCsgInfo = csgInfo;
}
- private CellIdentityTdscdma(CellIdentityTdscdma cid) {
+ private CellIdentityTdscdma(@NonNull CellIdentityTdscdma cid) {
this(cid.mMccStr, cid.mMncStr, cid.mLac, cid.mCid,
cid.mCpid, cid.mUarfcn, cid.mAlphaLong,
cid.mAlphaShort, cid.mAdditionalPlmns, cid.mCsgInfo);
}
/** @hide */
- public CellIdentityTdscdma(android.hardware.radio.V1_0.CellIdentityTdscdma cid) {
+ public CellIdentityTdscdma(@NonNull android.hardware.radio.V1_0.CellIdentityTdscdma cid) {
this(cid.mcc, cid.mnc, cid.lac, cid.cid, cid.cpid, CellInfo.UNAVAILABLE, "", "",
Collections.emptyList(), null);
}
/** @hide */
- public CellIdentityTdscdma(android.hardware.radio.V1_2.CellIdentityTdscdma cid) {
+ public CellIdentityTdscdma(@NonNull android.hardware.radio.V1_2.CellIdentityTdscdma cid) {
this(cid.base.mcc, cid.base.mnc, cid.base.lac, cid.base.cid, cid.base.cpid,
cid.uarfcn, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort,
Collections.emptyList(), null);
}
/** @hide */
- public CellIdentityTdscdma(android.hardware.radio.V1_5.CellIdentityTdscdma cid) {
+ public CellIdentityTdscdma(@NonNull android.hardware.radio.V1_5.CellIdentityTdscdma cid) {
this(cid.base.base.mcc, cid.base.base.mnc, cid.base.base.lac, cid.base.base.cid,
cid.base.base.cpid, cid.base.uarfcn, cid.base.operatorNames.alphaLong,
cid.base.operatorNames.alphaShort,
@@ -130,7 +136,7 @@
mAdditionalPlmns, null);
}
- CellIdentityTdscdma copy() {
+ @NonNull CellIdentityTdscdma copy() {
return new CellIdentityTdscdma(this);
}
diff --git a/telephony/java/android/telephony/CellIdentityWcdma.java b/telephony/java/android/telephony/CellIdentityWcdma.java
index 9be42a1..15e491b 100644
--- a/telephony/java/android/telephony/CellIdentityWcdma.java
+++ b/telephony/java/android/telephony/CellIdentityWcdma.java
@@ -23,6 +23,7 @@
import android.telephony.gsm.GsmCellLocation;
import android.text.TextUtils;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -83,34 +84,38 @@
*
* @hide
*/
- public CellIdentityWcdma (int lac, int cid, int psc, int uarfcn,
- String mccStr, String mncStr, String alphal, String alphas,
- @NonNull List<String> additionalPlmns,
- @Nullable ClosedSubscriberGroupInfo csgInfo) {
+ public CellIdentityWcdma(int lac, int cid, int psc, int uarfcn, @Nullable String mccStr,
+ @Nullable String mncStr, @Nullable String alphal, @Nullable String alphas,
+ @NonNull List<String> additionalPlmns, @Nullable ClosedSubscriberGroupInfo csgInfo) {
super(TAG, CellInfo.TYPE_WCDMA, mccStr, mncStr, alphal, alphas);
mLac = inRangeOrUnavailable(lac, 0, MAX_LAC);
mCid = inRangeOrUnavailable(cid, 0, MAX_CID);
mPsc = inRangeOrUnavailable(psc, 0, MAX_PSC);
mUarfcn = inRangeOrUnavailable(uarfcn, 0, MAX_UARFCN);
- mAdditionalPlmns = additionalPlmns;
+ mAdditionalPlmns = new ArrayList<>(additionalPlmns.size());
+ for (String plmn : additionalPlmns) {
+ if (isValidPlmn(plmn)) {
+ mAdditionalPlmns.add(plmn);
+ }
+ }
mCsgInfo = csgInfo;
}
/** @hide */
- public CellIdentityWcdma(android.hardware.radio.V1_0.CellIdentityWcdma cid) {
+ public CellIdentityWcdma(@NonNull android.hardware.radio.V1_0.CellIdentityWcdma cid) {
this(cid.lac, cid.cid, cid.psc, cid.uarfcn, cid.mcc, cid.mnc, "", "",
Collections.emptyList(), null);
}
/** @hide */
- public CellIdentityWcdma(android.hardware.radio.V1_2.CellIdentityWcdma cid) {
+ public CellIdentityWcdma(@NonNull android.hardware.radio.V1_2.CellIdentityWcdma cid) {
this(cid.base.lac, cid.base.cid, cid.base.psc, cid.base.uarfcn,
cid.base.mcc, cid.base.mnc, cid.operatorNames.alphaLong,
cid.operatorNames.alphaShort, Collections.emptyList(), null);
}
/** @hide */
- public CellIdentityWcdma(android.hardware.radio.V1_5.CellIdentityWcdma cid) {
+ public CellIdentityWcdma(@NonNull android.hardware.radio.V1_5.CellIdentityWcdma cid) {
this(cid.base.base.lac, cid.base.base.cid, cid.base.base.psc, cid.base.base.uarfcn,
cid.base.base.mcc, cid.base.base.mnc, cid.base.operatorNames.alphaLong,
cid.base.operatorNames.alphaShort, cid.additionalPlmns,
@@ -118,7 +123,7 @@
? new ClosedSubscriberGroupInfo(cid.optionalCsgInfo.csgInfo()) : null);
}
- private CellIdentityWcdma(CellIdentityWcdma cid) {
+ private CellIdentityWcdma(@NonNull CellIdentityWcdma cid) {
this(cid.mLac, cid.mCid, cid.mPsc, cid.mUarfcn, cid.mMccStr,
cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort, cid.mAdditionalPlmns, cid.mCsgInfo);
}
@@ -131,7 +136,7 @@
mAlphaLong, mAlphaShort, mAdditionalPlmns, null);
}
- CellIdentityWcdma copy() {
+ @NonNull CellIdentityWcdma copy() {
return new CellIdentityWcdma(this);
}
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 5cd7cf8..8e83c4c 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -2543,7 +2543,7 @@
MmsManager m = (MmsManager) context.getSystemService(Context.MMS_SERVICE);
if (m != null) {
m.sendMultimediaMessage(getSubscriptionId(), contentUri, locationUrl, configOverrides,
- sentIntent);
+ sentIntent, 0L /* messageId */);
}
}
@@ -2581,7 +2581,7 @@
MmsManager m = (MmsManager) context.getSystemService(Context.MMS_SERVICE);
if (m != null) {
m.downloadMultimediaMessage(getSubscriptionId(), locationUrl, contentUri,
- configOverrides, downloadedIntent);
+ configOverrides, downloadedIntent, 0L /* messageId */);
}
}
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
index 80491cd..0fdcbc5 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
@@ -584,6 +584,25 @@
assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
}
+ @Test
+ public void testRollbackApexDataDirectories_Phase1() throws Exception {
+ int sessionId = Install.single(TEST_APEX_WITH_APK_V2).setStaged().setEnableRollback()
+ .commit();
+ InstallUtils.waitForSessionReady(sessionId);
+ }
+
+ @Test
+ public void testRollbackApexDataDirectories_Phase2() throws Exception {
+ RollbackInfo available = RollbackUtils.getAvailableRollback(APK_IN_APEX_TESTAPEX_NAME);
+
+ RollbackUtils.rollback(available.getRollbackId(), TEST_APEX_WITH_APK_V2);
+ RollbackInfo committed = RollbackUtils.getCommittedRollbackById(available.getRollbackId());
+
+ // Note: The app is not rolled back until after the rollback is staged
+ // and the device has been rebooted.
+ InstallUtils.waitForSessionReady(committed.getCommittedSessionId());
+ }
+
private static void runShellCommand(String cmd) {
ParcelFileDescriptor pfd = InstrumentationRegistry.getInstrumentation().getUiAutomation()
.executeShellCommand(cmd);
diff --git a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
index 672cbb0..ce2f7c5 100644
--- a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
+++ b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
@@ -16,6 +16,8 @@
package com.android.tests.rollback.host;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import static org.testng.Assert.assertThrows;
@@ -53,6 +55,17 @@
private static final String APK_IN_APEX_TESTAPEX_NAME = "com.android.apex.apkrollback.test";
+ private static final String TEST_SUBDIR = "/subdir/";
+
+ private static final String TEST_FILENAME_1 = "test_file.txt";
+ private static final String TEST_STRING_1 = "hello this is a test";
+ private static final String TEST_FILENAME_2 = "another_file.txt";
+ private static final String TEST_STRING_2 = "this is a different file";
+ private static final String TEST_FILENAME_3 = "also.xyz";
+ private static final String TEST_STRING_3 = "also\n a\n test\n string";
+ private static final String TEST_FILENAME_4 = "one_more.test";
+ private static final String TEST_STRING_4 = "once more unto the test";
+
@Before
public void setUp() throws Exception {
if (!getDevice().isAdbRoot()) {
@@ -77,6 +90,10 @@
getDevice().executeShellCommand(
"rm -f /system/apex/" + APK_IN_APEX_TESTAPEX_NAME + "*.apex "
+ "/data/apex/active/" + APK_IN_APEX_TESTAPEX_NAME + "*.apex");
+ getDevice().executeShellCommand(
+ "rm -rf " + apexDataDirDeSys(APK_IN_APEX_TESTAPEX_NAME) + "*");
+ getDevice().executeShellCommand(
+ "rm -rf " + apexDataDirCe(APK_IN_APEX_TESTAPEX_NAME, 0) + "*");
getDevice().reboot();
}
@@ -245,15 +262,7 @@
@Test
public void testRollbackApexWithApk() throws Exception {
getDevice().uninstallPackage("com.android.cts.install.lib.testapp.A");
- CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(getBuild());
- final String fileName = APK_IN_APEX_TESTAPEX_NAME + "_v1.apex";
- final File apex = buildHelper.getTestFile(fileName);
- if (!getDevice().isAdbRoot()) {
- getDevice().enableAdbRoot();
- }
- getDevice().remountSystemWritable();
- assertTrue(getDevice().pushFile(apex, "/system/apex/" + fileName));
- getDevice().reboot();
+ pushTestApex();
runPhase("testRollbackApexWithApk_Phase1");
getDevice().reboot();
runPhase("testRollbackApexWithApk_Phase2");
@@ -267,15 +276,7 @@
@Test
public void testRollbackApexWithApkCrashing() throws Exception {
getDevice().uninstallPackage("com.android.cts.install.lib.testapp.A");
- CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(getBuild());
- final String fileName = APK_IN_APEX_TESTAPEX_NAME + "_v1.apex";
- final File apex = buildHelper.getTestFile(fileName);
- if (!getDevice().isAdbRoot()) {
- getDevice().enableAdbRoot();
- }
- getDevice().remountSystemWritable();
- assertTrue(getDevice().pushFile(apex, "/system/apex/" + fileName));
- getDevice().reboot();
+ pushTestApex();
// Install an apex with apk that crashes
runPhase("testRollbackApexWithApkCrashing_Phase1");
@@ -289,6 +290,102 @@
runPhase("testRollbackApexWithApkCrashing_Phase3");
}
+ /**
+ * Tests that data in DE_sys apex data directory is restored when apex is rolled back.
+ */
+ @Test
+ public void testRollbackApexDataDirectories_DeSys() throws Exception {
+ pushTestApex();
+
+ // Push files to apex data directory
+ String oldFilePath1 = apexDataDirDeSys(APK_IN_APEX_TESTAPEX_NAME) + "/" + TEST_FILENAME_1;
+ String oldFilePath2 =
+ apexDataDirDeSys(APK_IN_APEX_TESTAPEX_NAME) + TEST_SUBDIR + TEST_FILENAME_2;
+ assertTrue(getDevice().pushString(TEST_STRING_1, oldFilePath1));
+ assertTrue(getDevice().pushString(TEST_STRING_2, oldFilePath2));
+
+ // Install new version of the APEX with rollback enabled
+ runPhase("testRollbackApexDataDirectories_Phase1");
+ getDevice().reboot();
+
+ // Replace files in data directory
+ getDevice().deleteFile(oldFilePath1);
+ getDevice().deleteFile(oldFilePath2);
+ String newFilePath3 = apexDataDirDeSys(APK_IN_APEX_TESTAPEX_NAME) + "/" + TEST_FILENAME_3;
+ String newFilePath4 =
+ apexDataDirDeSys(APK_IN_APEX_TESTAPEX_NAME) + TEST_SUBDIR + TEST_FILENAME_4;
+ assertTrue(getDevice().pushString(TEST_STRING_3, newFilePath3));
+ assertTrue(getDevice().pushString(TEST_STRING_4, newFilePath4));
+
+ // Roll back the APEX
+ runPhase("testRollbackApexDataDirectories_Phase2");
+ getDevice().reboot();
+
+ // Verify that old files have been restored and new files are gone
+ assertEquals(TEST_STRING_1, getDevice().pullFileContents(oldFilePath1));
+ assertEquals(TEST_STRING_2, getDevice().pullFileContents(oldFilePath2));
+ assertNull(getDevice().pullFile(newFilePath3));
+ assertNull(getDevice().pullFile(newFilePath4));
+ }
+
+ /**
+ * Tests that data in CE apex data directory is restored when apex is rolled back.
+ */
+ @Test
+ public void testRollbackApexDataDirectories_Ce() throws Exception {
+ pushTestApex();
+
+ // Push files to apex data directory
+ String oldFilePath1 = apexDataDirCe(APK_IN_APEX_TESTAPEX_NAME, 0) + "/" + TEST_FILENAME_1;
+ String oldFilePath2 =
+ apexDataDirCe(APK_IN_APEX_TESTAPEX_NAME, 0) + TEST_SUBDIR + TEST_FILENAME_2;
+ assertTrue(getDevice().pushString(TEST_STRING_1, oldFilePath1));
+ assertTrue(getDevice().pushString(TEST_STRING_2, oldFilePath2));
+
+ // Install new version of the APEX with rollback enabled
+ runPhase("testRollbackApexDataDirectories_Phase1");
+ getDevice().reboot();
+
+ // Replace files in data directory
+ getDevice().deleteFile(oldFilePath1);
+ getDevice().deleteFile(oldFilePath2);
+ String newFilePath3 = apexDataDirCe(APK_IN_APEX_TESTAPEX_NAME, 0) + "/" + TEST_FILENAME_3;
+ String newFilePath4 =
+ apexDataDirCe(APK_IN_APEX_TESTAPEX_NAME, 0) + TEST_SUBDIR + TEST_FILENAME_4;
+ assertTrue(getDevice().pushString(TEST_STRING_3, newFilePath3));
+ assertTrue(getDevice().pushString(TEST_STRING_4, newFilePath4));
+
+ // Roll back the APEX
+ runPhase("testRollbackApexDataDirectories_Phase2");
+ getDevice().reboot();
+
+ // Verify that old files have been restored and new files are gone
+ assertEquals(TEST_STRING_1, getDevice().pullFileContents(oldFilePath1));
+ assertEquals(TEST_STRING_2, getDevice().pullFileContents(oldFilePath2));
+ assertNull(getDevice().pullFile(newFilePath3));
+ assertNull(getDevice().pullFile(newFilePath4));
+ }
+
+ private void pushTestApex() throws Exception {
+ CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(getBuild());
+ final String fileName = APK_IN_APEX_TESTAPEX_NAME + "_v1.apex";
+ final File apex = buildHelper.getTestFile(fileName);
+ if (!getDevice().isAdbRoot()) {
+ getDevice().enableAdbRoot();
+ }
+ getDevice().remountSystemWritable();
+ assertTrue(getDevice().pushFile(apex, "/system/apex/" + fileName));
+ getDevice().reboot();
+ }
+
+ private static String apexDataDirDeSys(String apexName) {
+ return String.format("/data/misc/apexdata/%s", apexName);
+ }
+
+ private static String apexDataDirCe(String apexName, int userId) {
+ return String.format("/data/misc_ce/%d/apexdata/%s", userId, apexName);
+ }
+
private void crashProcess(String processName, int numberOfCrashes) throws Exception {
String pid = "";
String lastPid = "invalid";
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 31b3a50..1f1c0c1 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -123,8 +123,6 @@
boolean isWifiStandardSupported(int standard);
- boolean needs5GHzToAnyApBandConversion();
-
DhcpInfo getDhcpInfo();
boolean isScanAlwaysAvailable();
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 9a25106..76f9716 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -2802,29 +2802,6 @@
}
/**
- * Check if the device is dual mode capable i.e. supports concurrent STA + Soft AP.
- *
- * If the device is dual mode capable, it may require conversion of the user's Soft AP band
- * selection {@link SoftApConfiguration#mBand} from {@link SoftApConfiguration#BAND_5GHZ} to
- * include also {@link SoftApConfiguration#BAND_2GHZ}, since if the device is connected to a
- * 5GHz DFS channel as a STA, it may be unable to honor a request to start Soft AP on the same
- * DFS channel.
- *
- * @return {@code true} if dual mode STA + AP is supported by this device, {@code false}
- * otherwise.
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
- public boolean isDualModeSupported() {
- try {
- return mService.needs5GHzToAnyApBandConversion();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
* Return the DHCP-assigned addresses from the last successful DHCP request,
* if any.
* @return the DHCP information
diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java
index b467553..060c85c 100644
--- a/wifi/java/com/android/server/wifi/BaseWifiService.java
+++ b/wifi/java/com/android/server/wifi/BaseWifiService.java
@@ -38,6 +38,7 @@
import android.net.wifi.SoftApConfiguration;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
import android.net.wifi.WifiNetworkSuggestion;
import android.net.wifi.hotspot2.IProvisioningCallback;
import android.net.wifi.hotspot2.OsuProvider;
@@ -268,7 +269,8 @@
throw new UnsupportedOperationException();
}
- @Override
+ /** @deprecated use {@link WifiManager#isStaApConcurrencySupported()} */
+ @Deprecated
public boolean needs5GHzToAnyApBandConversion() {
throw new UnsupportedOperationException();
}
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
index 0c2876e..a189d50 100644
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
@@ -1928,16 +1928,6 @@
}
/**
- * Test behavior of {@link WifiManager#isDualModeSupported()} ()}
- */
- @Test
- public void testIsDualModeSupported() throws Exception {
- when(mWifiService.needs5GHzToAnyApBandConversion()).thenReturn(true);
- assertTrue(mWifiManager.isDualModeSupported());
- verify(mWifiService).needs5GHzToAnyApBandConversion();
- }
-
- /**
* Test behavior of {@link WifiManager#is5GHzBandSupported()}
*/
@Test