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

Commit 3c918591 authored by zhaoyuhan's avatar zhaoyuhan
Browse files

Intercepting activites that could cause lock task mode violation in ActivityStartInterceptor.

Test: Manual
Test: atest WmTests:ActivityRecordTests
Test: atest WmTests:ActivityStartInterceptorTest
Test: atest WmTests:LockTaskControllerTest
Bug: b/131614258
Screenshot: https://screenshot.googleplex.com/hPy1b9NgkNj
Change-Id: I771d98509005fe8789ad6c4f5ceefd1460a8316d
parent 2f269667
Loading
Loading
Loading
Loading
+86 −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.internal.app;

import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
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 in lock task
 * mode. The intent to start this activity must be created with the static factory method provided
 * below.
 */
public class BlockedAppActivity extends AlertActivity {

    private static final String TAG = "BlockedAppActivity";
    private static final String PACKAGE_NAME = "com.android.internal.app";
    private static final String EXTRA_BLOCKED_PACKAGE = PACKAGE_NAME + ".extra.BLOCKED_PACKAGE";

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

        Intent intent = getIntent();
        int userId = intent.getIntExtra(Intent.EXTRA_USER_ID, /* defaultValue= */ -1);
        if (userId < 0) {
            Slog.wtf(TAG, "Invalid user: " + userId);
            finish();
            return;
        }

        String packageName = intent.getStringExtra(EXTRA_BLOCKED_PACKAGE);
        if (TextUtils.isEmpty(packageName)) {
            Slog.wtf(TAG, "Invalid package: " + packageName);
            finish();
            return;
        }

        CharSequence appLabel = getAppLabel(userId, packageName);

        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();
    }

    private CharSequence getAppLabel(int userId, String packageName) {
        PackageManager pm = getPackageManager();
        try {
            ApplicationInfo aInfo =
                    pm.getApplicationInfoAsUser(packageName, /* flags= */ 0, userId);
            return aInfo.loadLabel(pm);
        } catch (PackageManager.NameNotFoundException ne) {
            Slog.e(TAG, "Package " + packageName + " not found", ne);
        }
        return packageName;
    }


    /** Creates an intent that launches {@link BlockedAppActivity}. */
    public static Intent createIntent(int userId, String packageName) {
        return new Intent()
                .setClassName("android", BlockedAppActivity.class.getName())
                .putExtra(Intent.EXTRA_USER_ID, userId)
                .putExtra(EXTRA_BLOCKED_PACKAGE, packageName);
    }
}
+6 −0
Original line number Diff line number Diff line
@@ -4976,6 +4976,12 @@
                android:process=":ui">
        </activity>

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

        <activity android:name="com.android.settings.notification.NotificationAccessConfirmationActivity"
                  android:theme="@style/Theme.Dialog.Confirmation"
                  android:excludeFromRecents="true">
+7 −0
Original line number Diff line number Diff line
@@ -4922,6 +4922,13 @@
    <!-- Title for button to turn on work profile. [CHAR LIMIT=NONE] -->
    <string name="work_mode_turn_on">Turn on</string>

    <!-- Title of the dialog that is shown when the user tries to launch a suspended application [CHAR LIMIT=50] -->
    <string name="app_blocked_title">App is not available</string>
    <!-- Default message shown in the dialog that is shown when the user tries to launch a suspended application [CHAR LIMIT=NONE] -->
    <string name="app_blocked_message">
        <xliff:g id="app_name" example="Gmail">%1$s</xliff:g> is not available right now.
    </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
@@ -3036,6 +3036,9 @@
  <java-symbol type="string" name="app_suspended_more_details" />
  <java-symbol type="string" name="app_suspended_default_message" />

  <java-symbol type="string" name="app_blocked_title" />
  <java-symbol type="string" name="app_blocked_message" />

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

+16 −9
Original line number Diff line number Diff line
@@ -1633,12 +1633,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        requestedVrComponent = (aInfo.requestedVrComponent == null) ?
                null : ComponentName.unflattenFromString(aInfo.requestedVrComponent);

        lockTaskLaunchMode = aInfo.lockTaskLaunchMode;
        if (info.applicationInfo.isPrivilegedApp()
                && (lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_ALWAYS
                || lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_NEVER)) {
            lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_DEFAULT;
        }
        lockTaskLaunchMode = getLockTaskLaunchMode(aInfo, options);

        if (options != null) {
            pendingOptions = options;
@@ -1646,13 +1641,25 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
            if (usageReport != null) {
                appTimeTracker = new AppTimeTracker(usageReport);
            }
            final boolean useLockTask = pendingOptions.getLockTaskMode();
            // Gets launch display id from options. It returns INVALID_DISPLAY if not set.
            mHandoverLaunchDisplayId = options.getLaunchDisplayId();
        }
    }

    static int getLockTaskLaunchMode(ActivityInfo aInfo, @Nullable ActivityOptions options) {
        int lockTaskLaunchMode = aInfo.lockTaskLaunchMode;
        if (aInfo.applicationInfo.isPrivilegedApp()
                && (lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_ALWAYS
                || lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_NEVER)) {
            lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_DEFAULT;
        }
        if (options != null) {
            final boolean useLockTask = options.getLockTaskMode();
            if (useLockTask && lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_DEFAULT) {
                lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
            }
            // Gets launch display id from options. It returns INVALID_DISPLAY if not set.
            mHandoverLaunchDisplayId = options.getLaunchDisplayId();
        }
        return lockTaskLaunchMode;
    }

    @Override
Loading