Skip to content

Commit 6c42754

Browse files
committed
Merge tag 'android-security-13.0.0_r13' into cr-11.0
Android security 13.0.0 release 13 Change-Id: I58470309dff8c373a9b59c743d63fdec2cb0c0a1
2 parents 95aedd0 + 90881fe commit 6c42754

7 files changed

Lines changed: 299 additions & 18 deletions

File tree

packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
import com.android.systemui.plugins.FalsingManager;
7979
import com.android.systemui.shared.system.SysUiStatsLog;
8080
import com.android.systemui.statusbar.policy.ConfigurationController;
81+
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
8182
import com.android.systemui.statusbar.policy.KeyguardStateController;
8283
import com.android.systemui.statusbar.policy.UserSwitcherController;
8384
import com.android.systemui.util.ViewController;
@@ -386,7 +387,8 @@ public KeyguardSecurityContainerController(KeyguardSecurityContainer view,
386387
FalsingA11yDelegate falsingA11yDelegate,
387388
TelephonyManager telephonyManager,
388389
ViewMediatorCallback viewMediatorCallback,
389-
AudioManager audioManager
390+
AudioManager audioManager,
391+
DeviceProvisionedController deviceProvisionedController
390392
) {
391393
super(view);
392394
mLockPatternUtils = lockPatternUtils;
@@ -411,6 +413,7 @@ public KeyguardSecurityContainerController(KeyguardSecurityContainer view,
411413
mTelephonyManager = telephonyManager;
412414
mViewMediatorCallback = viewMediatorCallback;
413415
mAudioManager = audioManager;
416+
mDeviceProvisionedController = deviceProvisionedController;
414417
}
415418

416419
@Override
@@ -752,8 +755,11 @@ public boolean showNextSecurityScreenOrFinish(boolean authenticated, int targetU
752755
case SimPuk:
753756
// Shortcut for SIM PIN/PUK to go to directly to user's security screen or home
754757
SecurityMode securityMode = mSecurityModel.getSecurityMode(targetUserId);
755-
if (securityMode == SecurityMode.None && mLockPatternUtils.isLockScreenDisabled(
756-
KeyguardUpdateMonitor.getCurrentUser())) {
758+
boolean isLockscreenDisabled = mLockPatternUtils.isLockScreenDisabled(
759+
KeyguardUpdateMonitor.getCurrentUser())
760+
|| !mDeviceProvisionedController.isUserSetup(targetUserId);
761+
762+
if (securityMode == SecurityMode.None && isLockscreenDisabled) {
757763
finish = true;
758764
eventSubtype = BOUNCER_DISMISS_SIM;
759765
uiEvent = BouncerUiEvent.BOUNCER_DISMISS_SIM;

packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import java.io.PrintWriter;
5252
import java.util.ArrayList;
5353
import java.util.List;
54+
import java.util.Map;
5455
import java.util.Set;
5556

5657
import javax.inject.Inject;
@@ -144,6 +145,10 @@ protected void setBGHandler(H handler) {
144145
protected void setListening(boolean listening) {
145146
mListening = listening;
146147
if (listening) {
148+
// System UI could be restarted while ops are active, so fetch the currently active ops
149+
// once System UI starts listening again.
150+
fetchCurrentActiveOps();
151+
147152
mAppOps.startWatchingActive(OPS, this);
148153
mAppOps.startWatchingNoted(OPS, this);
149154
mAudioManager.registerAudioRecordingCallback(mAudioRecordingCallback, mBGHandler);
@@ -176,6 +181,29 @@ protected void setListening(boolean listening) {
176181
}
177182
}
178183

184+
private void fetchCurrentActiveOps() {
185+
List<AppOpsManager.PackageOps> packageOps = mAppOps.getPackagesForOps(OPS);
186+
for (AppOpsManager.PackageOps op : packageOps) {
187+
for (AppOpsManager.OpEntry entry : op.getOps()) {
188+
for (Map.Entry<String, AppOpsManager.AttributedOpEntry> attributedOpEntry :
189+
entry.getAttributedOpEntries().entrySet()) {
190+
if (attributedOpEntry.getValue().isRunning()) {
191+
onOpActiveChanged(
192+
entry.getOpStr(),
193+
op.getUid(),
194+
op.getPackageName(),
195+
/* attributionTag= */ attributedOpEntry.getKey(),
196+
/* active= */ true,
197+
// AppOpsManager doesn't have a way to fetch attribution flags or
198+
// chain ID given an op entry, so default them to none.
199+
AppOpsManager.ATTRIBUTION_FLAGS_NONE,
200+
AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE);
201+
}
202+
}
203+
}
204+
}
205+
}
206+
179207
/**
180208
* Adds a callback that will get notifified when an AppOp of the type the controller tracks
181209
* changes

packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
import com.android.systemui.plugins.ActivityStarter;
7272
import com.android.systemui.plugins.FalsingManager;
7373
import com.android.systemui.statusbar.policy.ConfigurationController;
74+
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
7475
import com.android.systemui.statusbar.policy.KeyguardStateController;
7576
import com.android.systemui.statusbar.policy.UserSwitcherController;
7677
import com.android.systemui.util.settings.GlobalSettings;
@@ -208,7 +209,8 @@ public void setup() {
208209
mConfigurationController, mFalsingCollector, mFalsingManager,
209210
mUserSwitcherController, mFeatureFlags, mGlobalSettings,
210211
mSessionTracker, Optional.of(mSideFpsController), mFalsingA11yDelegate,
211-
mTelephonyManager, mViewMediatorCallback, mAudioManager);
212+
mTelephonyManager, mViewMediatorCallback, mAudioManager,
213+
mock(DeviceProvisionedController.class));
212214
}
213215

214216
@Test

packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import static android.hardware.SensorPrivacyManager.Sensors.CAMERA;
2020
import static android.hardware.SensorPrivacyManager.Sensors.MICROPHONE;
2121

22+
import static com.google.common.truth.Truth.assertThat;
23+
2224
import static junit.framework.TestCase.assertFalse;
2325

2426
import static org.junit.Assert.assertEquals;
@@ -66,6 +68,7 @@
6668

6769
import java.util.Collections;
6870
import java.util.List;
71+
import java.util.Map;
6972

7073
@SmallTest
7174
@RunWith(AndroidTestingRunner.class)
@@ -157,6 +160,204 @@ public void testStopListening() {
157160
verify(mSensorPrivacyController, times(1)).removeCallback(mController);
158161
}
159162

163+
@Test
164+
public void startListening_fetchesCurrentActive_none() {
165+
when(mAppOpsManager.getPackagesForOps(AppOpsControllerImpl.OPS))
166+
.thenReturn(List.of());
167+
168+
mController.setListening(true);
169+
170+
assertThat(mController.getActiveAppOps()).isEmpty();
171+
}
172+
173+
/** Regression test for b/294104969. */
174+
@Test
175+
public void startListening_fetchesCurrentActive_oneActive() {
176+
AppOpsManager.PackageOps packageOps = createPackageOp(
177+
"package.test",
178+
/* packageUid= */ 2,
179+
AppOpsManager.OPSTR_FINE_LOCATION,
180+
/* isRunning= */ true);
181+
when(mAppOpsManager.getPackagesForOps(AppOpsControllerImpl.OPS))
182+
.thenReturn(List.of(packageOps));
183+
184+
// WHEN we start listening
185+
mController.setListening(true);
186+
187+
// THEN the active list has the op
188+
List<AppOpItem> list = mController.getActiveAppOps();
189+
assertEquals(1, list.size());
190+
AppOpItem first = list.get(0);
191+
assertThat(first.getPackageName()).isEqualTo("package.test");
192+
assertThat(first.getUid()).isEqualTo(2);
193+
assertThat(first.getCode()).isEqualTo(AppOpsManager.OP_FINE_LOCATION);
194+
}
195+
196+
@Test
197+
public void startListening_fetchesCurrentActive_multiplePackages() {
198+
AppOpsManager.PackageOps packageOps1 = createPackageOp(
199+
"package.one",
200+
/* packageUid= */ 1,
201+
AppOpsManager.OPSTR_FINE_LOCATION,
202+
/* isRunning= */ true);
203+
AppOpsManager.PackageOps packageOps2 = createPackageOp(
204+
"package.two",
205+
/* packageUid= */ 2,
206+
AppOpsManager.OPSTR_FINE_LOCATION,
207+
/* isRunning= */ false);
208+
AppOpsManager.PackageOps packageOps3 = createPackageOp(
209+
"package.three",
210+
/* packageUid= */ 3,
211+
AppOpsManager.OPSTR_FINE_LOCATION,
212+
/* isRunning= */ true);
213+
when(mAppOpsManager.getPackagesForOps(AppOpsControllerImpl.OPS))
214+
.thenReturn(List.of(packageOps1, packageOps2, packageOps3));
215+
216+
// WHEN we start listening
217+
mController.setListening(true);
218+
219+
// THEN the active list has the ops
220+
List<AppOpItem> list = mController.getActiveAppOps();
221+
assertEquals(2, list.size());
222+
223+
AppOpItem item0 = list.get(0);
224+
assertThat(item0.getPackageName()).isEqualTo("package.one");
225+
assertThat(item0.getUid()).isEqualTo(1);
226+
assertThat(item0.getCode()).isEqualTo(AppOpsManager.OP_FINE_LOCATION);
227+
228+
AppOpItem item1 = list.get(1);
229+
assertThat(item1.getPackageName()).isEqualTo("package.three");
230+
assertThat(item1.getUid()).isEqualTo(3);
231+
assertThat(item1.getCode()).isEqualTo(AppOpsManager.OP_FINE_LOCATION);
232+
}
233+
234+
@Test
235+
public void startListening_fetchesCurrentActive_multipleEntries() {
236+
AppOpsManager.PackageOps packageOps = mock(AppOpsManager.PackageOps.class);
237+
when(packageOps.getUid()).thenReturn(1);
238+
when(packageOps.getPackageName()).thenReturn("package.one");
239+
240+
// Entry 1
241+
AppOpsManager.OpEntry entry1 = mock(AppOpsManager.OpEntry.class);
242+
when(entry1.getOpStr()).thenReturn(AppOpsManager.OPSTR_PHONE_CALL_MICROPHONE);
243+
AppOpsManager.AttributedOpEntry attributed1 = mock(AppOpsManager.AttributedOpEntry.class);
244+
when(attributed1.isRunning()).thenReturn(true);
245+
when(entry1.getAttributedOpEntries()).thenReturn(Map.of("tag", attributed1));
246+
// Entry 2
247+
AppOpsManager.OpEntry entry2 = mock(AppOpsManager.OpEntry.class);
248+
when(entry2.getOpStr()).thenReturn(AppOpsManager.OPSTR_CAMERA);
249+
AppOpsManager.AttributedOpEntry attributed2 = mock(AppOpsManager.AttributedOpEntry.class);
250+
when(attributed2.isRunning()).thenReturn(true);
251+
when(entry2.getAttributedOpEntries()).thenReturn(Map.of("tag", attributed2));
252+
// Entry 3
253+
AppOpsManager.OpEntry entry3 = mock(AppOpsManager.OpEntry.class);
254+
when(entry3.getOpStr()).thenReturn(AppOpsManager.OPSTR_FINE_LOCATION);
255+
AppOpsManager.AttributedOpEntry attributed3 = mock(AppOpsManager.AttributedOpEntry.class);
256+
when(attributed3.isRunning()).thenReturn(false);
257+
when(entry3.getAttributedOpEntries()).thenReturn(Map.of("tag", attributed3));
258+
259+
when(packageOps.getOps()).thenReturn(List.of(entry1, entry2, entry3));
260+
when(mAppOpsManager.getPackagesForOps(AppOpsControllerImpl.OPS))
261+
.thenReturn(List.of(packageOps));
262+
263+
// WHEN we start listening
264+
mController.setListening(true);
265+
266+
// THEN the active list has the ops
267+
List<AppOpItem> list = mController.getActiveAppOps();
268+
assertEquals(2, list.size());
269+
270+
AppOpItem first = list.get(0);
271+
assertThat(first.getPackageName()).isEqualTo("package.one");
272+
assertThat(first.getUid()).isEqualTo(1);
273+
assertThat(first.getCode()).isEqualTo(AppOpsManager.OP_PHONE_CALL_MICROPHONE);
274+
275+
AppOpItem second = list.get(1);
276+
assertThat(second.getPackageName()).isEqualTo("package.one");
277+
assertThat(second.getUid()).isEqualTo(1);
278+
assertThat(second.getCode()).isEqualTo(AppOpsManager.OP_CAMERA);
279+
}
280+
281+
@Test
282+
public void startListening_fetchesCurrentActive_multipleAttributes() {
283+
AppOpsManager.PackageOps packageOps = mock(AppOpsManager.PackageOps.class);
284+
when(packageOps.getUid()).thenReturn(1);
285+
when(packageOps.getPackageName()).thenReturn("package.one");
286+
AppOpsManager.OpEntry entry = mock(AppOpsManager.OpEntry.class);
287+
when(entry.getOpStr()).thenReturn(AppOpsManager.OPSTR_RECORD_AUDIO);
288+
289+
AppOpsManager.AttributedOpEntry attributed1 = mock(AppOpsManager.AttributedOpEntry.class);
290+
when(attributed1.isRunning()).thenReturn(false);
291+
AppOpsManager.AttributedOpEntry attributed2 = mock(AppOpsManager.AttributedOpEntry.class);
292+
when(attributed2.isRunning()).thenReturn(true);
293+
AppOpsManager.AttributedOpEntry attributed3 = mock(AppOpsManager.AttributedOpEntry.class);
294+
when(attributed3.isRunning()).thenReturn(true);
295+
when(entry.getAttributedOpEntries()).thenReturn(
296+
Map.of("attr1", attributed1, "attr2", attributed2, "attr3", attributed3));
297+
298+
when(packageOps.getOps()).thenReturn(List.of(entry));
299+
when(mAppOpsManager.getPackagesForOps(AppOpsControllerImpl.OPS))
300+
.thenReturn(List.of(packageOps));
301+
302+
// WHEN we start listening
303+
mController.setListening(true);
304+
305+
// THEN the active list has the ops
306+
List<AppOpItem> list = mController.getActiveAppOps();
307+
// Multiple attributes get merged into one entry in the active ops
308+
assertEquals(1, list.size());
309+
310+
AppOpItem first = list.get(0);
311+
assertThat(first.getPackageName()).isEqualTo("package.one");
312+
assertThat(first.getUid()).isEqualTo(1);
313+
assertThat(first.getCode()).isEqualTo(AppOpsManager.OP_RECORD_AUDIO);
314+
}
315+
316+
/** Regression test for b/294104969. */
317+
@Test
318+
public void addCallback_existingCallbacksNotifiedOfCurrentActive() {
319+
AppOpsManager.PackageOps packageOps1 = createPackageOp(
320+
"package.one",
321+
/* packageUid= */ 1,
322+
AppOpsManager.OPSTR_FINE_LOCATION,
323+
/* isRunning= */ true);
324+
AppOpsManager.PackageOps packageOps2 = createPackageOp(
325+
"package.two",
326+
/* packageUid= */ 2,
327+
AppOpsManager.OPSTR_RECORD_AUDIO,
328+
/* isRunning= */ true);
329+
AppOpsManager.PackageOps packageOps3 = createPackageOp(
330+
"package.three",
331+
/* packageUid= */ 3,
332+
AppOpsManager.OPSTR_PHONE_CALL_MICROPHONE,
333+
/* isRunning= */ true);
334+
when(mAppOpsManager.getPackagesForOps(AppOpsControllerImpl.OPS))
335+
.thenReturn(List.of(packageOps1, packageOps2, packageOps3));
336+
337+
// WHEN we start listening
338+
mController.addCallback(
339+
new int[]{AppOpsManager.OP_RECORD_AUDIO, AppOpsManager.OP_FINE_LOCATION},
340+
mCallback);
341+
mTestableLooper.processAllMessages();
342+
343+
// THEN the callback is notified of the current active ops it cares about
344+
verify(mCallback).onActiveStateChanged(
345+
AppOpsManager.OP_FINE_LOCATION,
346+
/* uid= */ 1,
347+
"package.one",
348+
true);
349+
verify(mCallback).onActiveStateChanged(
350+
AppOpsManager.OP_RECORD_AUDIO,
351+
/* uid= */ 2,
352+
"package.two",
353+
true);
354+
verify(mCallback, never()).onActiveStateChanged(
355+
AppOpsManager.OP_PHONE_CALL_MICROPHONE,
356+
/* uid= */ 3,
357+
"package.three",
358+
true);
359+
}
360+
160361
@Test
161362
public void addCallback_includedCode() {
162363
mController.addCallback(
@@ -673,6 +874,22 @@ public void testPhoneCallCameraFilteredWhenCameraDisabled() {
673874
assertEquals(AppOpsManager.OP_PHONE_CALL_CAMERA, list.get(cameraIdx).getCode());
674875
}
675876

877+
private AppOpsManager.PackageOps createPackageOp(
878+
String packageName, int packageUid, String opStr, boolean isRunning) {
879+
AppOpsManager.PackageOps packageOps = mock(AppOpsManager.PackageOps.class);
880+
when(packageOps.getPackageName()).thenReturn(packageName);
881+
when(packageOps.getUid()).thenReturn(packageUid);
882+
AppOpsManager.OpEntry entry = mock(AppOpsManager.OpEntry.class);
883+
when(entry.getOpStr()).thenReturn(opStr);
884+
AppOpsManager.AttributedOpEntry attributed = mock(AppOpsManager.AttributedOpEntry.class);
885+
when(attributed.isRunning()).thenReturn(isRunning);
886+
887+
when(packageOps.getOps()).thenReturn(Collections.singletonList(entry));
888+
when(entry.getAttributedOpEntries()).thenReturn(Map.of("tag", attributed));
889+
890+
return packageOps;
891+
}
892+
676893
private class TestHandler extends AppOpsControllerImpl.H {
677894
TestHandler(Looper looper) {
678895
mController.super(looper);

services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ public class CompanionDeviceManagerService extends SystemService {
132132
"debug.cdm.cdmservice.removal_time_window";
133133

134134
private static final long ASSOCIATION_REMOVAL_TIME_WINDOW_DEFAULT = DAYS.toMillis(90);
135+
private static final int MAX_CN_LENGTH = 500;
135136

136137
private final ActivityManager mActivityManager;
137138
private final OnPackageVisibilityChangeListener mOnPackageVisibilityChangeListener;
@@ -619,8 +620,10 @@ public void disassociate(int associationId) {
619620
public PendingIntent requestNotificationAccess(ComponentName component, int userId)
620621
throws RemoteException {
621622
String callingPackage = component.getPackageName();
622-
checkCanCallNotificationApi(callingPackage);
623-
// TODO: check userId.
623+
checkCanCallNotificationApi(callingPackage, userId);
624+
if (component.flattenToString().length() > MAX_CN_LENGTH) {
625+
throw new IllegalArgumentException("Component name is too long.");
626+
}
624627
final long identity = Binder.clearCallingIdentity();
625628
try {
626629
return PendingIntent.getActivityAsUser(getContext(),
@@ -643,7 +646,7 @@ public PendingIntent requestNotificationAccess(ComponentName component, int user
643646
@Deprecated
644647
@Override
645648
public boolean hasNotificationAccess(ComponentName component) throws RemoteException {
646-
checkCanCallNotificationApi(component.getPackageName());
649+
checkCanCallNotificationApi(component.getPackageName(), getCallingUserId());
647650
NotificationManager nm = getContext().getSystemService(NotificationManager.class);
648651
return nm.isNotificationListenerAccessGranted(component);
649652
}
@@ -800,8 +803,7 @@ public void createAssociation(String packageName, String macAddress, int userId,
800803
legacyCreateAssociation(userId, macAddress, packageName, null);
801804
}
802805

803-
private void checkCanCallNotificationApi(String callingPackage) {
804-
final int userId = getCallingUserId();
806+
private void checkCanCallNotificationApi(String callingPackage, int userId) {
805807
enforceCallerIsSystemOr(userId, callingPackage);
806808

807809
if (getCallingUid() == SYSTEM_UID) return;

0 commit comments

Comments
 (0)