当前位置: 首页 > news >正文

Android 15.0 启动app时设置密码锁(升级到framework层判断)

 framework层判断包名是否加锁,如果加锁了,启动systemui的输入密码的activity,验证通过后,继续启动activity


diff --git a/LA.QSSI.15.0_MC9452/frameworks/base/packages/SystemUI/AndroidManifest.xml b/LA.QSSI.15.0_MC9452/frameworks/base/packages/SystemUI/AndroidManifest.xml
index e7cc18748d9..f5063022ca0 100644
--- a/LA.QSSI.15.0_MC9452/frameworks/base/packages/SystemUI/AndroidManifest.xml
+++ b/LA.QSSI.15.0_MC9452/frameworks/base/packages/SystemUI/AndroidManifest.xml
@@ -1119,5 +1119,13 @@android:showForAllUsers="true"android:theme="@style/ShortcutHelperTheme"android:excludeFromRecents="true" />
+
+        <activity android:name=".lock.PasswordVerifyActivity"
+            android:exported="true"
+            android:theme="@android:style/Theme.DeviceDefault.Dialog.Alert"
+            android:excludeFromRecents="true"
+            android:taskAffinity=""
+            android:launchMode="singleTask">
+        </activity></application></manifest>
diff --git a/LA.QSSI.15.0_MC9452/frameworks/base/packages/SystemUI/res/values-zh-rCN/strings.xml b/LA.QSSI.15.0_MC9452/frameworks/base/packages/SystemUI/res/values-zh-rCN/strings.xml
index 6859d55c16c..73d7b143843 100644
--- a/LA.QSSI.15.0_MC9452/frameworks/base/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/LA.QSSI.15.0_MC9452/frameworks/base/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -1404,4 +1404,13 @@<string name="text_both">两者</string><string name="title_input_joystick_switch">启用虚拟摇杆</string>
+
+    <string name="verify_title">请输入密码</string>
+    <string name="verify_message">应用 <xliff:g name="pkg">%1$s</xliff:g> 已被锁定</string>
+    <string name="verify_button">验证</string>
+    <string name="verify_cancel">取消</string>
+    <string name="verify_success">验证成功</string>
+    <string name="verify_failed">密码错误,请重试</string>
+    <string name="verify_cancelled">已取消验证</string>
+</resources>
diff --git a/LA.QSSI.15.0_MC9452/frameworks/base/packages/SystemUI/res/values/strings.xml b/LA.QSSI.15.0_MC9452/frameworks/base/packages/SystemUI/res/values/strings.xml
index 433983d0619..9b630b537bc 100644
--- a/LA.QSSI.15.0_MC9452/frameworks/base/packages/SystemUI/res/values/strings.xml
+++ b/LA.QSSI.15.0_MC9452/frameworks/base/packages/SystemUI/res/values/strings.xml
@@ -3669,4 +3669,12 @@<string name="text_both">Both</string><string name="title_input_joystick_switch">Enable virtual joystick</string>
+
+    <string name="verify_title">Enter Password</string>
+    <string name="verify_message">App <xliff:g name="pkg">%1$s</xliff:g> is locked</string>
+    <string name="verify_button">Verify</string>
+    <string name="verify_cancel">Cancel</string>
+    <string name="verify_success">Verification succeeded</string>
+    <string name="verify_failed">Incorrect password, try again</string>
+    <string name="verify_cancelled">Verification cancelled</string></resources>
diff --git a/LA.QSSI.15.0_MC9452/frameworks/base/packages/SystemUI/src/com/android/systemui/lock/PasswordVerifyActivity.java b/LA.QSSI.15.0_MC9452/frameworks/base/packages/SystemUI/src/com/android/systemui/lock/PasswordVerifyActivity.java
new file mode 100644
index 00000000000..8891b31bb79
--- /dev/null
+++ b/LA.QSSI.15.0_MC9452/frameworks/base/packages/SystemUI/src/com/android/systemui/lock/PasswordVerifyActivity.java
@@ -0,0 +1,105 @@
+package com.android.systemui.lock;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.os.SystemProperties;
+import android.text.InputType;
+import android.widget.EditText;
+import android.widget.Toast;
+import com.android.systemui.R;
+import android.util.Log;
+import java.util.List;
+import android.provider.Settings;
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+
+
+public class PasswordVerifyActivity extends Activity {
+
+    private String lockedPackage;
+    private static final String PASSWORD_KEY = "persist.sys.lock_app.setting.password";
+    private static final String DEFAULT_PASSWORD = "soft1024";
+    private static final String TAG = "zdx_pwd_verify";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Log.d(TAG, "onCreate, pid=" + android.os.Process.myPid());
+
+        lockedPackage = getIntent().getStringExtra("locked_package");
+        if (lockedPackage == null || lockedPackage.isEmpty()) {
+            Toast.makeText(this, "No package specified", Toast.LENGTH_SHORT).show();
+            // Log.e(TAG, "lockedPackage is null or empty, finishing...");
+            finish();
+            return;
+        }
+
+
+        showPasswordDialog();
+    }
+
+    private void showPasswordDialog() {
+        EditText input = new EditText(this);
+        input.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
+
+
+
+
+        new AlertDialog.Builder(this)
+            .setTitle(R.string.verify_title)
+            .setMessage(getString(R.string.verify_message, ""))
+            .setView(input)
+            .setCancelable(false)
+            .setPositiveButton(R.string.verify_button, (dialog, which) -> {
+                String inputPassword = input.getText().toString();
+                String correctPassword = SystemProperties.get(PASSWORD_KEY, DEFAULT_PASSWORD);
+
+                // Log.d(TAG, "User entered password: " + inputPassword);
+
+                if (correctPassword.equals(inputPassword)) {
+                    // Log.d(TAG, "Password correct. Saving timestamp for " + lockedPackage);
+                    long now = System.currentTimeMillis();
+                    boolean result = Settings.Secure.putLong(
+                        getContentResolver(),
+                        "lock_app_last_verified_" + lockedPackage,
+                        now
+                    );
+                    // Log.d(TAG, "Timestamp saved: " + now + ", success=" + result);
+                    Toast.makeText(this, R.string.verify_success, Toast.LENGTH_SHORT).show();
+
+                    launchTargetApp(lockedPackage);
+                    finish();
+                } else {
+                    Toast.makeText(this, R.string.verify_failed, Toast.LENGTH_SHORT).show();
+                    showPasswordDialog(); // retry
+                }
+            })
+            .setNegativeButton(R.string.verify_cancel, (dialog, which) -> {
+                Toast.makeText(this, R.string.verify_cancelled, Toast.LENGTH_SHORT).show();
+                finish();
+            })
+            .show();
+    }
+
+    private void launchTargetApp(String packageName) {
+        // Log.d(TAG, "launchTargetApp: " + packageName);
+        PackageManager pm = getPackageManager();
+        Intent intent = pm.getLaunchIntentForPackage(packageName);
+        if (intent != null) {
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            // Log.d(TAG, "Launching intent: " + intent);
+            startActivity(intent);
+        } else {
+            // Log.e(TAG, "Unable to get launch intent for " + packageName);
+            Toast.makeText(this, "Unable to launch " + packageName, Toast.LENGTH_SHORT).show();
+        }
+    }
+
+}
diff --git a/LA.QSSI.15.0_MC9452/frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java b/LA.QSSI.15.0_MC9452/frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
index 2ef876d16c5..a38bc89e096 100644
--- a/LA.QSSI.15.0_MC9452/frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/LA.QSSI.15.0_MC9452/frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -149,6 +149,14 @@ import java.lang.annotation.RetentionPolicy;import java.text.DateFormat;import java.util.Date;+
+import android.content.Intent;
+import android.content.ComponentName;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.Slog;
+import android.os.SystemProperties;
+import android.content.SharedPreferences;/*** Controller for interpreting how and then launching an activity.*
@@ -161,6 +169,7 @@ class ActivityStarter {private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
+    private static final String LOCK_APP_ENABLE_KEY = "persist.sys.lock_app.enabled";private static final int INVALID_LAUNCH_MODE = -1;@@ -1504,6 +1513,29 @@ class ActivityStarter {: (customCallingUid >= 0 ? customCallingUid : actualCallingUid);}+    private boolean isAppLocked(String pkg) {
+        boolean isLockEnabled = SystemProperties.getBoolean(LOCK_APP_ENABLE_KEY, false);
+        if (!isLockEnabled) return false;
+        String locked_apps = android.provider.Settings.Secure.getString(mService.mContext.getContentResolver(), "locked_apps");
+        Slog.i(TAG, "locked app = " + locked_apps);
+        return locked_apps != null && java.util.Arrays.asList(locked_apps.split(",")).contains(pkg);
+    }
+
+    private boolean isPasswordPassedRecently(String pkg) {
+        long lastTime = Settings.Secure.getLong(mService.mContext.getContentResolver(),"lock_app_last_verified_" + pkg, 0L);
+        boolean recentlyPassed = System.currentTimeMillis() - lastTime < 2 * 60 * 60 * 1000; // 2小时
+        return recentlyPassed;
+    }
+
+    private void launchPasswordVerifyActivity(int userId, String pkg) {
+        android.content.Intent intent = new android.content.Intent();
+        intent.setComponent(new android.content.ComponentName(
+            "com.android.systemui", "com.android.systemui.lock.PasswordVerifyActivity"));
+        intent.putExtra("locked_package", pkg);
+        intent.setFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
+        mService.mContext.startActivityAsUser(intent, android.os.UserHandle.of(userId));
+    }
+/*** Start an activity while most of preliminary checks has been done and caller has been* confirmed that holds necessary permissions to do so.
@@ -1518,6 +1550,15 @@ class ActivityStarter {int result = START_CANCELED;final Task startedActivityRootTask;+        // === App Lock Check Start ===
+        // 判断app 包名是否已经锁定
+        // Slog.e(TAG, " startActivityUnchecked r.packageName =  "+  r.packageName );
+        if (r != null && isAppLocked(r.packageName) && !isPasswordPassedRecently(r.packageName)) {
+            launchPasswordVerifyActivity(r.mUserId, r.packageName);
+            return START_SUCCESS;
+        }
+        // === App Lock Check End ===
+// Create a transition now to record the original intent of actions taken within// startActivityInner. Otherwise, logic in startActivityInner could start a different// transition based on a sub-action.
diff --git a/LA.QSSI.15.0_MC9452/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/LA.QSSI.15.0_MC9452/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index 892da04a4e4..3e6355c5428 100644
--- a/LA.QSSI.15.0_MC9452/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/LA.QSSI.15.0_MC9452/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -173,6 +173,14 @@ import java.util.function.Predicate;import java.util.Arrays;import android.os.AsyncTask;+import android.content.Intent;
+import android.content.ComponentName;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.Slog;
+import android.os.SystemProperties;
+import android.content.SharedPreferences;
+import vendor.qti.hardware.servicetracker.V1_2.IServicetracker;// TODO: This class has become a dumping ground. Let's
@@ -188,6 +196,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {private static final String TAG_ROOT_TASK = TAG + POSTFIX_ROOT_TASK;private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;static final String TAG_TASKS = TAG + POSTFIX_TASKS;
+    private static final String LOCK_APP_ENABLE_KEY = "persist.sys.lock_app.enabled";/** How long we wait until giving up on the last activity telling us it is idle. */private static final int IDLE_TIMEOUT = 10 * 1000 * Build.HW_TIMEOUT_MULTIPLIER;
@@ -2876,6 +2885,31 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {}}+
+    private boolean isAppLocked(String pkg) {
+        boolean isLockEnabled = SystemProperties.getBoolean(LOCK_APP_ENABLE_KEY, false);
+        if (!isLockEnabled) return false;
+        String locked_apps = android.provider.Settings.Secure.getString(mService.mContext.getContentResolver(), "locked_apps");
+        Slog.i(TAG, "locked app = " + locked_apps);
+        return locked_apps != null && java.util.Arrays.asList(locked_apps.split(",")).contains(pkg);
+    }
+
+    private boolean isPasswordPassedRecently(String pkg) {
+        long lastTime = Settings.Secure.getLong(mService.mContext.getContentResolver(),"lock_app_last_verified_" + pkg, 0L);
+        boolean recentlyPassed = System.currentTimeMillis() - lastTime < 2 * 60 * 60 * 1000; // 2小时
+        return recentlyPassed;
+    }
+
+    private void launchPasswordVerifyActivity(int userId, String pkg) {
+        android.content.Intent intent = new android.content.Intent();
+        intent.setComponent(new android.content.ComponentName(
+            "com.android.systemui", "com.android.systemui.lock.PasswordVerifyActivity"));
+        intent.putExtra("locked_package", pkg);
+        intent.setFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
+        mService.mContext.startActivityAsUser(intent, android.os.UserHandle.of(userId));
+    }
+
+/*** Start the given task from the recent tasks. Do not hold WM global lock when calling this* method to avoid potential deadlock or permission deny by UriGrantsManager when resolving
@@ -2927,6 +2961,16 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {"startActivityFromRecents: Task " + taskId + " not found.");}+                final ActivityRecord rootActivity = task.getRootActivity();
+                if (rootActivity != null) {
+                    String packageName = rootActivity.packageName;
+                    // 判断app 包名是否已经锁定
+                    if ( isAppLocked(packageName) && !isPasswordPassedRecently(packageName)) {
+                        launchPasswordVerifyActivity(rootActivity.mUserId, packageName);
+                        return 0;
+                    }
+                }
+if (moveHomeTaskForward) {// We always want to return to the home activity instead of the recents// activity from whatever is started from the recents activity, so move
diff --git a/LA.QSSI.15.0_MC9452/packages/apps/Launcher3/src/com/android/launcher3/Launcher.java b/LA.QSSI.15.0_MC9452/packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
index a6a8d193ba6..02ab1f65978 100644
--- a/LA.QSSI.15.0_MC9452/packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
+++ b/LA.QSSI.15.0_MC9452/packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
@@ -2217,36 +2217,36 @@ public class Launcher extends StatefulActivity<LauncherState>// TODO:升级到framework层进行加锁app的判断
-        boolean isLockEnabled = SystemProperties.getBoolean("persist.sys.lock_app.enabled", false);
-        if (isLockEnabled){
-            String app_list = getLockedAppList();
-
-            ComponentName component = intent.getComponent();
-            String packageName = component != null ? component.getPackageName() : "";
-
-            if (!packageName.isEmpty()) {
-                List<String> lockedApps = Arrays.asList(app_list.split(","));
-                if (lockedApps.contains(packageName)) {
-                    long now = System.currentTimeMillis();
-                    Long lastSuccessTime = mPasswordPassedMap.get(packageName);
-                    if (lastSuccessTime != null && (now - lastSuccessTime < PASSWORD_VALID_DURATION_MS)) {
-                        // 最近已通过密码验证,直接启动
-                        return super.startActivitySafely(v, intent, item);
-                    }
-
-                    // 否则弹出密码输入框
-                    showPasswordDialog(() -> {
-                        mPasswordPassedMap.put(packageName, System.currentTimeMillis());
-                        try {
-                            super.startActivity(intent, null);
-                        } catch (Exception e) {
-                            e.printStackTrace();
-                        }
-                    });
-                    return null;
-                }
-            }
-        }
+        // boolean isLockEnabled = SystemProperties.getBoolean("persist.sys.lock_app.enabled", false);
+        // if (isLockEnabled){
+        //     String app_list = getLockedAppList();
+
+        //     ComponentName component = intent.getComponent();
+        //     String packageName = component != null ? component.getPackageName() : "";
+
+        //     if (!packageName.isEmpty()) {
+        //         List<String> lockedApps = Arrays.asList(app_list.split(","));
+        //         if (lockedApps.contains(packageName)) {
+        //             long now = System.currentTimeMillis();
+        //             Long lastSuccessTime = mPasswordPassedMap.get(packageName);
+        //             if (lastSuccessTime != null && (now - lastSuccessTime < PASSWORD_VALID_DURATION_MS)) {
+        //                 // 最近已通过密码验证,直接启动
+        //                 return super.startActivitySafely(v, intent, item);
+        //             }
+
+        //             // 否则弹出密码输入框
+        //             showPasswordDialog(() -> {
+        //                 mPasswordPassedMap.put(packageName, System.currentTimeMillis());
+        //                 try {
+        //                     super.startActivity(intent, null);
+        //                 } catch (Exception e) {
+        //                     e.printStackTrace();
+        //                 }
+        //             });
+        //             return null;
+        //         }
+        //     }
+        // }if (!hasBeenResumed()) {RunnableList result = new RunnableList();

http://www.lryc.cn/news/609640.html

相关文章:

  • 《时间之隙:内存溢出》
  • 《基于电阻抗断层成像(EIT)的触觉传感器:物理模拟与机器学习的创新结合》论文解读
  • RocketMQ与Kafka 消费者组的‌重平衡操作消息顺序性对比
  • 实现建筑环境自动控制,楼宇自控技术提升舒适与安全
  • 【前端】三件套基础介绍
  • 规则方法关系抽取-笔记总结
  • Postman 四种请求体格式全解析:区别、用法及 Spring Boot 接收指南
  • 实习005 (web后端springboot)
  • 【后端】Java static 关键字详解
  • 从零开始搞定类与对象(中)
  • Matplotlib与PySide6兼容性问题及解决方案
  • open-webui pipelines报404, ‘Filter pipeline.exporter not found‘
  • 基于Express+Ejs实现带登录认证的多模块增删改查后台管理系统
  • C++ 浅谈Robin Hood Hash 算法
  • 3ds Max 渲染效率提升指南:从场景设计优化开始
  • 【0基础3ds Max】常用快捷键
  • 【Linux下Java应用自动重启守护教程】
  • 【大模型】3D因果卷积动图怎么画
  • Linux—yum仓库及NFS网络共享服务
  • [QMT量化交易小白入门]-七十六、从tick数据中获取高频交易的量价背离信号
  • 验证码等待时间技术在酒店自助入住、美容自助与社区场景中的应用必要性研究—仙盟创梦IDE
  • Dynamic Programming【DP】2
  • 9.感知机、神经网络
  • Antlr学习笔记 01、maven配置Antlr4插件案例Demo
  • 中标喜讯 | 安畅检测成功中标海南工信大脑(二期)软件测评服务
  • [Oracle] TO_NUMBER()函数
  • 【分享】拼团交易平台系统,分布式、高并发、微服务
  • 豆包1.6+PromptPilot实战:构建智能品牌评价情感分类系统的技术探索
  • Jetbrains IDE总是弹出“需要身份验证”窗口
  • uniapp 基础(三)