Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5c5cdad7 authored by Maurice Lam's avatar Maurice Lam Committed by Android (Google) Code Review
Browse files

Merge "Roll forward "Show error dialog if activity is blocked from streaming""

parents 35839833 de16f717
Loading
Loading
Loading
Loading
+80 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.internal.app;

import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Slog;

import com.android.internal.R;

/**
 * A dialog shown to the user when they try to launch an app that is not allowed on a virtual
 * device. The intent to start this activity must be created with the static factory method provided
 * below.
 */
public class BlockedAppStreamingActivity extends AlertActivity {

    private static final String TAG = "BlockedAppStreamingActivity";
    private static final String PACKAGE_NAME = "com.android.internal.app";
    private static final String EXTRA_BLOCKED_ACTIVITY_INFO =
            PACKAGE_NAME + ".extra.BLOCKED_ACTIVITY_INFO";
    private static final String EXTRA_STREAMED_DEVICE = PACKAGE_NAME + ".extra.STREAMED_DEVICE";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Intent intent = getIntent();
        CharSequence appLabel = null;
        ActivityInfo activityInfo = intent.getParcelableExtra(EXTRA_BLOCKED_ACTIVITY_INFO);
        if (activityInfo != null) {
            appLabel = activityInfo.loadLabel(getPackageManager());
        }

        if (TextUtils.isEmpty(appLabel)) {
            Slog.wtf(TAG, "Invalid activity info: " + activityInfo);
            finish();
            return;
        }

        CharSequence streamedDeviceName = intent.getCharSequenceExtra(EXTRA_STREAMED_DEVICE);
        if (!TextUtils.isEmpty(streamedDeviceName)) {
            mAlertParams.mTitle = getString(R.string.app_streaming_blocked_title, appLabel);
            mAlertParams.mMessage =
                    getString(R.string.app_streaming_blocked_message, streamedDeviceName);
        } else {
            mAlertParams.mTitle = getString(R.string.app_blocked_title);
            mAlertParams.mMessage = getString(R.string.app_blocked_message, appLabel);
        }
        mAlertParams.mPositiveButtonText = getString(android.R.string.ok);
        setupAlert();
    }

    /**
     * Creates an intent that launches {@link BlockedAppStreamingActivity} when app streaming is
     * blocked.
     */
    public static Intent createIntent(ActivityInfo activityInfo, CharSequence streamedDeviceName) {
        return new Intent()
                .setClassName("android", BlockedAppStreamingActivity.class.getName())
                .putExtra(EXTRA_BLOCKED_ACTIVITY_INFO, activityInfo)
                .putExtra(EXTRA_STREAMED_DEVICE, streamedDeviceName);
    }
}
+6 −0
Original line number Diff line number Diff line
@@ -6591,6 +6591,12 @@
                android:process=":ui">
        </activity>

        <activity android:name="com.android.internal.app.BlockedAppStreamingActivity"
            android:theme="@style/Theme.Dialog.Confirmation"
            android:excludeFromRecents="true"
            android:process=":ui">
        </activity>

        <activity android:name="com.android.internal.app.LaunchAfterAuthenticationActivity"
                  android:theme="@style/Theme.Translucent.NoTitleBar"
                  android:excludeFromRecents="true"
+9 −0
Original line number Diff line number Diff line
@@ -5469,6 +5469,15 @@
        <xliff:g id="app_name" example="Gmail">%1$s</xliff:g> is not available right now.
    </string>

    <!-- Title of the dialog shown when an app is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
    <string name="app_streaming_blocked_title"><xliff:g id="activity" example="Permission dialog">%1$s</xliff:g> unavailable</string>
    <!-- Message shown when an app is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
    <string name="app_streaming_blocked_message" product="tv">This can’t be accessed on your <xliff:g id="device" example="Chromebook">%1$s</xliff:g> at this time. Try on your Android TV device instead.</string>
    <!-- Message shown when an app is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
    <string name="app_streaming_blocked_message" product="tablet">This can’t be accessed on your <xliff:g id="device" example="Chromebook">%1$s</xliff:g> at this time. Try on your tablet instead.</string>
    <!-- Message shown when an app is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
    <string name="app_streaming_blocked_message" product="default">This can’t be accessed on your <xliff:g id="device" example="Chromebook">%1$s</xliff:g> at this time. Try on your phone instead.</string>

    <!-- Message displayed in dialog when app is too old to run on this verison of android. [CHAR LIMIT=NONE] -->
    <string name="deprecated_target_sdk_message">This app was built for an older version of Android and may not work properly. Try checking for updates, or contact the developer.</string>
    <!-- Title for button to see application detail in app store which it came from - it may allow user to update to newer version. [CHAR LIMIT=50] -->
+3 −0
Original line number Diff line number Diff line
@@ -3288,6 +3288,9 @@
  <java-symbol type="string" name="app_blocked_title" />
  <java-symbol type="string" name="app_blocked_message" />

  <java-symbol type="string" name="app_streaming_blocked_title" />
  <java-symbol type="string" name="app_streaming_blocked_message" />

  <!-- Used internally for assistant to launch activity transitions -->
  <java-symbol type="id" name="cross_task_transition" />

+25 −10
Original line number Diff line number Diff line
@@ -37,8 +37,11 @@ import android.util.Slog;
import android.view.Display;
import android.window.DisplayWindowPolicyController;

import com.android.internal.app.BlockedAppStreamingActivity;

import java.util.List;
import java.util.Set;
import java.util.function.Consumer;


/**
@@ -48,6 +51,9 @@ class GenericWindowPolicyController extends DisplayWindowPolicyController {

    private static final String TAG = "VirtualDeviceManager";

    private static final ComponentName BLOCKED_APP_STREAMING_COMPONENT =
            new ComponentName("android", BlockedAppStreamingActivity.class.getName());

    /**
     * If required, allow the secure activity to display on remote device since
     * {@link android.os.Build.VERSION_CODES#TIRAMISU}.
@@ -61,6 +67,7 @@ class GenericWindowPolicyController extends DisplayWindowPolicyController {
    private final ArraySet<ComponentName> mAllowedActivities;
    @Nullable
    private final ArraySet<ComponentName> mBlockedActivities;
    private Consumer<ActivityInfo> mActivityBlockedCallback;

    @NonNull
    final ArraySet<Integer> mRunningUids = new ArraySet<>();
@@ -81,10 +88,12 @@ class GenericWindowPolicyController extends DisplayWindowPolicyController {
            @NonNull ArraySet<UserHandle> allowedUsers,
            @Nullable Set<ComponentName> allowedActivities,
            @Nullable Set<ComponentName> blockedActivities,
            @NonNull ActivityListener activityListener) {
            @NonNull ActivityListener activityListener,
            @NonNull Consumer<ActivityInfo> activityBlockedCallback) {
        mAllowedUsers = allowedUsers;
        mAllowedActivities = allowedActivities == null ? null : new ArraySet<>(allowedActivities);
        mBlockedActivities = blockedActivities == null ? null : new ArraySet<>(blockedActivities);
        mActivityBlockedCallback = activityBlockedCallback;
        setInterestedWindowFlags(windowFlags, systemWindowFlags);
        mActivityListener = activityListener;
    }
@@ -96,6 +105,7 @@ class GenericWindowPolicyController extends DisplayWindowPolicyController {
        for (int i = 0; i < activityCount; i++) {
            final ActivityInfo aInfo = activities.get(i);
            if (!canContainActivity(aInfo, /* windowFlags= */ 0, /* systemWindowFlags= */ 0)) {
                mActivityBlockedCallback.accept(aInfo);
                return false;
            }
        }
@@ -105,7 +115,11 @@ class GenericWindowPolicyController extends DisplayWindowPolicyController {
    @Override
    public boolean keepActivityOnWindowFlagsChanged(ActivityInfo activityInfo, int windowFlags,
            int systemWindowFlags) {
        return canContainActivity(activityInfo, windowFlags, systemWindowFlags);
        if (!canContainActivity(activityInfo, windowFlags, systemWindowFlags)) {
            mActivityBlockedCallback.accept(activityInfo);
            return false;
        }
        return true;
    }

    @Override
@@ -140,22 +154,23 @@ class GenericWindowPolicyController extends DisplayWindowPolicyController {
        if ((activityInfo.flags & FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES) == 0) {
            return false;
        }
        ComponentName activityComponent = activityInfo.getComponentName();
        if (BLOCKED_APP_STREAMING_COMPONENT.equals(activityComponent)) {
            // The error dialog alerting users that streaming is blocked is always allowed.
            return true;
        }
        final UserHandle activityUser =
                UserHandle.getUserHandleForUid(activityInfo.applicationInfo.uid);
        if (!mAllowedUsers.contains(activityUser)) {
            Slog.d(TAG, "Virtual device activity not allowed from user " + activityUser);
            return false;
        }
        if (mBlockedActivities != null
                && mBlockedActivities.contains(activityInfo.getComponentName())) {
            Slog.d(TAG,
                    "Virtual device blocking launch of " + activityInfo.getComponentName());
        if (mBlockedActivities != null && mBlockedActivities.contains(activityComponent)) {
            Slog.d(TAG, "Virtual device blocking launch of " + activityComponent);
            return false;
        }
        if (mAllowedActivities != null
                && !mAllowedActivities.contains(activityInfo.getComponentName())) {
            Slog.d(TAG,
                    activityInfo.getComponentName() + " is not in the allowed list.");
        if (mAllowedActivities != null && !mAllowedActivities.contains(activityComponent)) {
            Slog.d(TAG, activityComponent + " is not in the allowed list.");
            return false;
        }
        if (!CompatChanges.isChangeEnabled(ALLOW_SECURE_ACTIVITY_DISPLAY_ON_REMOTE_DEVICE,
Loading