Loading packages/CarSystemUI/res/values/config.xml +1 −0 Original line number Diff line number Diff line Loading @@ -111,5 +111,6 @@ <item>com.android.systemui.car.voicerecognition.ConnectedDeviceVoiceRecognitionNotifier</item> <item>com.android.systemui.car.window.SystemUIOverlayWindowManager</item> <item>com.android.systemui.car.volume.VolumeUI</item> <item>com.android.systemui.car.sideloaded.SideLoadedAppController</item> </string-array> </resources> packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java +7 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import com.android.systemui.biometrics.AuthController; import com.android.systemui.bubbles.dagger.BubbleModule; import com.android.systemui.car.navigationbar.CarNavigationBar; import com.android.systemui.car.notification.CarNotificationModule; import com.android.systemui.car.sideloaded.SideLoadedAppController; import com.android.systemui.car.statusbar.CarStatusBar; import com.android.systemui.car.statusbar.CarStatusBarModule; import com.android.systemui.car.voicerecognition.ConnectedDeviceVoiceRecognitionNotifier; Loading Loading @@ -192,4 +193,10 @@ public abstract class CarSystemUIBinder { @IntoMap @ClassKey(SystemUIOverlayWindowManager.class) public abstract SystemUI bindSystemUIPrimaryWindowManager(SystemUIOverlayWindowManager sysui); /** Inject into SideLoadedAppController. */ @Binds @IntoMap @ClassKey(SideLoadedAppController.class) public abstract SystemUI bindSideLoadedAppController(SideLoadedAppController sysui); } packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppController.java 0 → 100644 +73 −0 Original line number Diff line number Diff line /* * 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.systemui.car.sideloaded; import android.app.IActivityTaskManager; import android.content.Context; import android.os.RemoteException; import android.util.Log; import com.android.systemui.SystemUI; import javax.inject.Inject; import javax.inject.Singleton; /** * Controller responsible for detecting unsafe apps. */ @Singleton public class SideLoadedAppController extends SystemUI { private static final String TAG = SideLoadedAppController.class.getSimpleName(); private IActivityTaskManager mActivityTaskManager; private SideLoadedAppListener mSideLoadedAppListener; private SideLoadedAppDetector mSideLoadedAppDetector; private SideLoadedAppStateController mSideLoadedAppStateController; @Inject public SideLoadedAppController(Context context, IActivityTaskManager activityTaskManager, SideLoadedAppDetector sideLoadedAppDetector, SideLoadedAppListener sideLoadedAppListener, SideLoadedAppStateController sideLoadedAppStateController) { super(context); mSideLoadedAppDetector = sideLoadedAppDetector; mActivityTaskManager = activityTaskManager; mSideLoadedAppListener = sideLoadedAppListener; mSideLoadedAppStateController = sideLoadedAppStateController; } @Override public void start() { } @Override protected void onBootCompleted() { Log.i(TAG, "OnBootCompleted"); try { mActivityTaskManager.registerTaskStackListener(mSideLoadedAppListener); } catch (RemoteException e) { Log.e(TAG, "Could not register car side loaded app listener.", e); } if (mSideLoadedAppDetector.hasUnsafeInstalledApps()) { mSideLoadedAppStateController.onUnsafeInstalledAppsDetected(); } } } packages/CarSystemUI/src/com/android/systemui/car/sideloaded/CarSideLoadedAppDetector.java→packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppDetector.java +3 −3 Original line number Diff line number Diff line Loading @@ -42,15 +42,15 @@ import javax.inject.Singleton; * An app is considered safe if is a system app or installed through whitelisted sources. */ @Singleton public class CarSideLoadedAppDetector { private static final String TAG = "CarSideLoadedDetector"; public class SideLoadedAppDetector { private static final String TAG = SideLoadedAppDetector.class.getSimpleName(); private final PackageManager mPackageManager; private final CarDeviceProvisionedController mCarDeviceProvisionedController; private final List<String> mAllowedAppInstallSources; @Inject public CarSideLoadedAppDetector(@Main Resources resources, PackageManager packageManager, public SideLoadedAppDetector(@Main Resources resources, PackageManager packageManager, CarDeviceProvisionedController deviceProvisionedController) { mAllowedAppInstallSources = Arrays.asList( resources.getStringArray(R.array.config_allowedAppInstallSources)); Loading packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppListener.java 0 → 100644 +130 −0 Original line number Diff line number Diff line /* * 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.systemui.car.sideloaded; import android.app.ActivityManager; import android.app.ActivityManager.StackInfo; import android.app.IActivityTaskManager; import android.app.TaskStackListener; import android.content.ComponentName; import android.hardware.display.DisplayManager; import android.os.RemoteException; import android.util.Log; import android.view.Display; import java.util.List; import javax.inject.Inject; /** * A TaskStackListener to detect when an unsafe app is launched/foregrounded. */ public class SideLoadedAppListener extends TaskStackListener { private static final String TAG = SideLoadedAppListener.class.getSimpleName(); private IActivityTaskManager mActivityTaskManager; private DisplayManager mDisplayManager; private SideLoadedAppDetector mSideLoadedAppDetector; private SideLoadedAppStateController mSideLoadedAppStateController; @Inject SideLoadedAppListener(SideLoadedAppDetector sideLoadedAppDetector, IActivityTaskManager activityTaskManager, DisplayManager displayManager, SideLoadedAppStateController sideLoadedAppStateController) { mSideLoadedAppDetector = sideLoadedAppDetector; mActivityTaskManager = activityTaskManager; mDisplayManager = displayManager; mSideLoadedAppStateController = sideLoadedAppStateController; } @Override public void onTaskCreated(int taskId, ComponentName componentName) throws RemoteException { super.onTaskCreated(taskId, componentName); List<StackInfo> stackInfoList = mActivityTaskManager.getAllStackInfos(); ActivityManager.StackInfo stackInfo = getStackInfo(stackInfoList, taskId); if (stackInfo == null) { Log.e(TAG, "Stack info was not available for taskId: " + taskId); return; } if (!mSideLoadedAppDetector.isSafe(stackInfo)) { Display display = mDisplayManager.getDisplay(stackInfo.displayId); mSideLoadedAppStateController.onUnsafeTaskCreatedOnDisplay(display); } } @Override public void onTaskStackChanged() throws RemoteException { super.onTaskStackChanged(); Display[] displays = mDisplayManager.getDisplays(); for (Display display : displays) { // Note that the stackInfoList is ordered by recency. List<StackInfo> stackInfoList = mActivityTaskManager.getAllStackInfosOnDisplay(display.getDisplayId()); if (stackInfoList == null) { continue; } StackInfo stackInfo = getTopVisibleStackInfo(stackInfoList); if (stackInfo == null) { continue; } if (mSideLoadedAppDetector.isSafe(stackInfo)) { mSideLoadedAppStateController.onSafeTaskDisplayedOnDisplay(display); } else { mSideLoadedAppStateController.onUnsafeTaskDisplayedOnDisplay(display); } } } /** * Returns stack info for a given taskId. */ private ActivityManager.StackInfo getStackInfo( List<ActivityManager.StackInfo> stackInfoList, int taskId) { if (stackInfoList == null) { return null; } for (ActivityManager.StackInfo stackInfo : stackInfoList) { if (stackInfo.taskIds == null) { continue; } for (int stackTaskId : stackInfo.taskIds) { if (taskId == stackTaskId) { return stackInfo; } } } return null; } /** * Returns the first visible stackInfo. */ private ActivityManager.StackInfo getTopVisibleStackInfo( List<ActivityManager.StackInfo> stackInfoList) { for (ActivityManager.StackInfo stackInfo : stackInfoList) { if (stackInfo.visible) { return stackInfo; } } return null; } } Loading
packages/CarSystemUI/res/values/config.xml +1 −0 Original line number Diff line number Diff line Loading @@ -111,5 +111,6 @@ <item>com.android.systemui.car.voicerecognition.ConnectedDeviceVoiceRecognitionNotifier</item> <item>com.android.systemui.car.window.SystemUIOverlayWindowManager</item> <item>com.android.systemui.car.volume.VolumeUI</item> <item>com.android.systemui.car.sideloaded.SideLoadedAppController</item> </string-array> </resources>
packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java +7 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import com.android.systemui.biometrics.AuthController; import com.android.systemui.bubbles.dagger.BubbleModule; import com.android.systemui.car.navigationbar.CarNavigationBar; import com.android.systemui.car.notification.CarNotificationModule; import com.android.systemui.car.sideloaded.SideLoadedAppController; import com.android.systemui.car.statusbar.CarStatusBar; import com.android.systemui.car.statusbar.CarStatusBarModule; import com.android.systemui.car.voicerecognition.ConnectedDeviceVoiceRecognitionNotifier; Loading Loading @@ -192,4 +193,10 @@ public abstract class CarSystemUIBinder { @IntoMap @ClassKey(SystemUIOverlayWindowManager.class) public abstract SystemUI bindSystemUIPrimaryWindowManager(SystemUIOverlayWindowManager sysui); /** Inject into SideLoadedAppController. */ @Binds @IntoMap @ClassKey(SideLoadedAppController.class) public abstract SystemUI bindSideLoadedAppController(SideLoadedAppController sysui); }
packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppController.java 0 → 100644 +73 −0 Original line number Diff line number Diff line /* * 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.systemui.car.sideloaded; import android.app.IActivityTaskManager; import android.content.Context; import android.os.RemoteException; import android.util.Log; import com.android.systemui.SystemUI; import javax.inject.Inject; import javax.inject.Singleton; /** * Controller responsible for detecting unsafe apps. */ @Singleton public class SideLoadedAppController extends SystemUI { private static final String TAG = SideLoadedAppController.class.getSimpleName(); private IActivityTaskManager mActivityTaskManager; private SideLoadedAppListener mSideLoadedAppListener; private SideLoadedAppDetector mSideLoadedAppDetector; private SideLoadedAppStateController mSideLoadedAppStateController; @Inject public SideLoadedAppController(Context context, IActivityTaskManager activityTaskManager, SideLoadedAppDetector sideLoadedAppDetector, SideLoadedAppListener sideLoadedAppListener, SideLoadedAppStateController sideLoadedAppStateController) { super(context); mSideLoadedAppDetector = sideLoadedAppDetector; mActivityTaskManager = activityTaskManager; mSideLoadedAppListener = sideLoadedAppListener; mSideLoadedAppStateController = sideLoadedAppStateController; } @Override public void start() { } @Override protected void onBootCompleted() { Log.i(TAG, "OnBootCompleted"); try { mActivityTaskManager.registerTaskStackListener(mSideLoadedAppListener); } catch (RemoteException e) { Log.e(TAG, "Could not register car side loaded app listener.", e); } if (mSideLoadedAppDetector.hasUnsafeInstalledApps()) { mSideLoadedAppStateController.onUnsafeInstalledAppsDetected(); } } }
packages/CarSystemUI/src/com/android/systemui/car/sideloaded/CarSideLoadedAppDetector.java→packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppDetector.java +3 −3 Original line number Diff line number Diff line Loading @@ -42,15 +42,15 @@ import javax.inject.Singleton; * An app is considered safe if is a system app or installed through whitelisted sources. */ @Singleton public class CarSideLoadedAppDetector { private static final String TAG = "CarSideLoadedDetector"; public class SideLoadedAppDetector { private static final String TAG = SideLoadedAppDetector.class.getSimpleName(); private final PackageManager mPackageManager; private final CarDeviceProvisionedController mCarDeviceProvisionedController; private final List<String> mAllowedAppInstallSources; @Inject public CarSideLoadedAppDetector(@Main Resources resources, PackageManager packageManager, public SideLoadedAppDetector(@Main Resources resources, PackageManager packageManager, CarDeviceProvisionedController deviceProvisionedController) { mAllowedAppInstallSources = Arrays.asList( resources.getStringArray(R.array.config_allowedAppInstallSources)); Loading
packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppListener.java 0 → 100644 +130 −0 Original line number Diff line number Diff line /* * 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.systemui.car.sideloaded; import android.app.ActivityManager; import android.app.ActivityManager.StackInfo; import android.app.IActivityTaskManager; import android.app.TaskStackListener; import android.content.ComponentName; import android.hardware.display.DisplayManager; import android.os.RemoteException; import android.util.Log; import android.view.Display; import java.util.List; import javax.inject.Inject; /** * A TaskStackListener to detect when an unsafe app is launched/foregrounded. */ public class SideLoadedAppListener extends TaskStackListener { private static final String TAG = SideLoadedAppListener.class.getSimpleName(); private IActivityTaskManager mActivityTaskManager; private DisplayManager mDisplayManager; private SideLoadedAppDetector mSideLoadedAppDetector; private SideLoadedAppStateController mSideLoadedAppStateController; @Inject SideLoadedAppListener(SideLoadedAppDetector sideLoadedAppDetector, IActivityTaskManager activityTaskManager, DisplayManager displayManager, SideLoadedAppStateController sideLoadedAppStateController) { mSideLoadedAppDetector = sideLoadedAppDetector; mActivityTaskManager = activityTaskManager; mDisplayManager = displayManager; mSideLoadedAppStateController = sideLoadedAppStateController; } @Override public void onTaskCreated(int taskId, ComponentName componentName) throws RemoteException { super.onTaskCreated(taskId, componentName); List<StackInfo> stackInfoList = mActivityTaskManager.getAllStackInfos(); ActivityManager.StackInfo stackInfo = getStackInfo(stackInfoList, taskId); if (stackInfo == null) { Log.e(TAG, "Stack info was not available for taskId: " + taskId); return; } if (!mSideLoadedAppDetector.isSafe(stackInfo)) { Display display = mDisplayManager.getDisplay(stackInfo.displayId); mSideLoadedAppStateController.onUnsafeTaskCreatedOnDisplay(display); } } @Override public void onTaskStackChanged() throws RemoteException { super.onTaskStackChanged(); Display[] displays = mDisplayManager.getDisplays(); for (Display display : displays) { // Note that the stackInfoList is ordered by recency. List<StackInfo> stackInfoList = mActivityTaskManager.getAllStackInfosOnDisplay(display.getDisplayId()); if (stackInfoList == null) { continue; } StackInfo stackInfo = getTopVisibleStackInfo(stackInfoList); if (stackInfo == null) { continue; } if (mSideLoadedAppDetector.isSafe(stackInfo)) { mSideLoadedAppStateController.onSafeTaskDisplayedOnDisplay(display); } else { mSideLoadedAppStateController.onUnsafeTaskDisplayedOnDisplay(display); } } } /** * Returns stack info for a given taskId. */ private ActivityManager.StackInfo getStackInfo( List<ActivityManager.StackInfo> stackInfoList, int taskId) { if (stackInfoList == null) { return null; } for (ActivityManager.StackInfo stackInfo : stackInfoList) { if (stackInfo.taskIds == null) { continue; } for (int stackTaskId : stackInfo.taskIds) { if (taskId == stackTaskId) { return stackInfo; } } } return null; } /** * Returns the first visible stackInfo. */ private ActivityManager.StackInfo getTopVisibleStackInfo( List<ActivityManager.StackInfo> stackInfoList) { for (ActivityManager.StackInfo stackInfo : stackInfoList) { if (stackInfo.visible) { return stackInfo; } } return null; } }