diff options
-rw-r--r-- | Android.bp | 10 | ||||
-rw-r--r-- | AndroidManifest.xml | 8 | ||||
-rw-r--r-- | MODULE_LICENSE_APACHE2 | 0 | ||||
-rw-r--r-- | NOTICE | 190 | ||||
-rw-r--r-- | OWNERS | 15 | ||||
-rw-r--r-- | src/com/android/stk/StkAppInstaller.java | 87 | ||||
-rw-r--r-- | src/com/android/stk/StkAppService.java | 146 | ||||
-rw-r--r-- | src/com/android/stk/StkInputActivity.java | 7 | ||||
-rw-r--r-- | src/com/android/stk/ToneDialog.java | 8 |
9 files changed, 162 insertions, 309 deletions
@@ -1,9 +1,17 @@ // Copyright 2007-2008 The Android Open Source Project +package { + // http://go/android-license-faq + default_applicable_licenses: ["Android-Apache-2.0"], +} + android_app { name: "Stk", libs: ["telephony-common"], - static_libs: ["com.google.android.material_material"], + static_libs: [ + "com.google.android.material_material", + "androidx.legacy_legacy-support-core-utils", + ], srcs: ["**/*.java"], platform_apis: true, certificate: "platform", diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 063e042..6b841ce 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -26,10 +26,12 @@ <uses-permission android:name="android.permission.REAL_GET_TASKS"/> <uses-permission android:name="android.permission.RECEIVE_STK_COMMANDS" /> <uses-permission android:name="android.permission.SET_ACTIVITY_WATCHER" /> + <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" /> <uses-permission android:name="android.permission.START_ACTIVITIES_FROM_BACKGROUND" /> <uses-permission android:name="android.permission.USER_ACTIVITY" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> + <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <application android:icon="@drawable/ic_launcher_sim_toolkit" android:label="@string/app_name" @@ -109,7 +111,8 @@ android:taskAffinity="android.task.stk.StkLauncherActivity"> </activity> - <receiver android:name="com.android.stk.StkCmdReceiver"> + <receiver android:name="com.android.stk.StkCmdReceiver" + android:exported="true"> <intent-filter> <action android:name= "com.android.internal.stk.command" /> <action android:name= "com.android.internal.stk.session_end" /> @@ -118,7 +121,8 @@ </intent-filter> </receiver> - <receiver android:name="com.android.stk.BootCompletedReceiver"> + <receiver android:name="com.android.stk.BootCompletedReceiver" + android:exported="true"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.USER_INITIALIZE" /> diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2 deleted file mode 100644 index e69de29..0000000 --- a/MODULE_LICENSE_APACHE2 +++ /dev/null @@ -1,190 +0,0 @@ - - Copyright (c) 2005-2008, 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. - - 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. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - @@ -1,15 +1,2 @@ -amitmahajan@google.com -breadley@google.com -fionaxu@google.com -jackyu@google.com -hallliu@google.com -rgreenwalt@google.com -tgunn@google.com -jminjie@google.com -shuoq@google.com -refuhoo@google.com -nazaninb@google.com -sarahchin@google.com -dbright@google.com -xiaotonj@google.com +file:platform/frameworks/opt/telephony:/OWNERS diff --git a/src/com/android/stk/StkAppInstaller.java b/src/com/android/stk/StkAppInstaller.java index 4e386ee..fe25af6 100644 --- a/src/com/android/stk/StkAppInstaller.java +++ b/src/com/android/stk/StkAppInstaller.java @@ -16,66 +16,75 @@ package com.android.stk; -import com.android.internal.telephony.cat.CatLog; import com.android.internal.telephony.PhoneConstants; +import com.android.internal.telephony.cat.CatLog; +import com.android.internal.telephony.util.TelephonyUtils; import android.content.ComponentName; import android.content.Context; +import android.content.pm.IPackageManager; import android.content.pm.PackageManager; -import android.telephony.TelephonyManager; -import android.os.SystemProperties; +import android.os.Build; +import android.os.RemoteException; +import android.os.ServiceManager; /** * Application installer for SIM Toolkit. * */ -abstract class StkAppInstaller { - private static final String STK_MAIN_ACTIVITY = "com.android.stk.StkMain"; +final class StkAppInstaller { + private static final boolean DBG = TelephonyUtils.IS_DEBUGGABLE; private static final String LOG_TAG = new Object(){}.getClass().getEnclosingClass().getSimpleName(); private StkAppInstaller() { - CatLog.d(LOG_TAG, "init"); } - public static void install(Context context) { - setAppState(context, true); + static void installOrUpdate(Context context, String label) { + IPackageManager pm = IPackageManager.Stub.asInterface(ServiceManager.getService("package")); + if (pm != null) { + ComponentName component = new ComponentName(context, StkMain.class); + int userId = context.getUserId(); + int icon = R.drawable.ic_launcher_sim_toolkit; + try { + try { + if (label != null) { + pm.overrideLabelAndIcon(component, label, icon, userId); + } else { + pm.restoreLabelAndIcon(component, userId); + } + if (DBG) CatLog.d(LOG_TAG, "Set the label to " + label); + } catch (SecurityException e) { + CatLog.e(LOG_TAG, "Failed to set the label to " + label); + } + setAppState(pm, component, userId, true); + } catch (RemoteException e) { + CatLog.e(LOG_TAG, "Failed to enable SIM Toolkit"); + } + } } - public static void unInstall(Context context) { - setAppState(context, false); + static void uninstall(Context context) { + IPackageManager pm = IPackageManager.Stub.asInterface(ServiceManager.getService("package")); + if (pm != null) { + ComponentName component = new ComponentName(context, StkMain.class); + try { + setAppState(pm, component, context.getUserId(), false); + } catch (RemoteException e) { + CatLog.e(LOG_TAG, "Failed to disable SIM Toolkit"); + } + } } - private static void setAppState(Context context, boolean install) { - CatLog.d(LOG_TAG, "[setAppState]+"); - if (context == null) { - CatLog.d(LOG_TAG, "[setAppState]- no context, just return."); - return; - } - PackageManager pm = context.getPackageManager(); - if (pm == null) { - CatLog.d(LOG_TAG, "[setAppState]- no package manager, just return."); - return; - } - ComponentName cName = new ComponentName("com.android.stk", STK_MAIN_ACTIVITY); - int state = install ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED + static void setAppState(IPackageManager pm, ComponentName component, int userId, boolean enable) + throws RemoteException { + int current = pm.getComponentEnabledSetting(component, userId); + int expected = enable ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED : PackageManager.COMPONENT_ENABLED_STATE_DISABLED; - - if (((PackageManager.COMPONENT_ENABLED_STATE_ENABLED == state) && - (PackageManager.COMPONENT_ENABLED_STATE_ENABLED == - pm.getComponentEnabledSetting(cName))) || - ((PackageManager.COMPONENT_ENABLED_STATE_DISABLED == state) && - (PackageManager.COMPONENT_ENABLED_STATE_DISABLED == - pm.getComponentEnabledSetting(cName)))) { - CatLog.d(LOG_TAG, "Need not change app state!!"); - } else { - CatLog.d(LOG_TAG, "Change app state[" + install + "]"); - try { - pm.setComponentEnabledSetting(cName, state, PackageManager.DONT_KILL_APP); - } catch (Exception e) { - CatLog.d(LOG_TAG, "Could not change STK app state"); - } + if (current != expected) { + pm.setComponentEnabledSetting(component, expected, PackageManager.DONT_KILL_APP, + userId); + if (DBG) CatLog.d(LOG_TAG, "SIM Toolkit is " + (enable ? "enabled" : "disabled")); } - CatLog.d(LOG_TAG, "[setAppState]-"); } } diff --git a/src/com/android/stk/StkAppService.java b/src/com/android/stk/StkAppService.java index de37c9c..6aabba0 100644 --- a/src/com/android/stk/StkAppService.java +++ b/src/com/android/stk/StkAppService.java @@ -24,7 +24,7 @@ import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManager.RunningTaskInfo; import android.app.AlertDialog; -import android.app.HomeVisibilityObserver; +import android.app.HomeVisibilityListener; import android.app.KeyguardManager; import android.app.Notification; import android.app.NotificationChannel; @@ -119,7 +119,6 @@ public class StkAppService extends Service implements Runnable { protected LinkedList<DelayedCmd> mCmdsQ = null; protected boolean mCmdInProgress = false; protected int mStkServiceState = STATE_UNKNOWN; - protected int mSetupMenuState = STATE_NOT_EXIST; protected int mMenuState = StkMenuActivity.STATE_INIT; protected int mOpCode = -1; private Activity mActivityInstance = null; @@ -171,7 +170,7 @@ public class StkAppService extends Service implements Runnable { private AppInterface[] mStkService = null; private StkContext[] mStkContext = null; private int mSimCount = 0; - private HomeVisibilityObserver mHomeVisibilityObserver = null; + private HomeVisibilityListener mHomeVisibilityListener = null; private BroadcastReceiver mLocaleChangeReceiver = null; private TonePlayer mTonePlayer = null; private Vibrator mVibrator = null; @@ -369,7 +368,7 @@ public class StkAppService extends Service implements Runnable { } if (i == mSimCount) { stopSelf(); - StkAppInstaller.unInstall(mContext); + StkAppInstaller.uninstall(this); return; } } @@ -498,7 +497,7 @@ public class StkAppService extends Service implements Runnable { CatLog.d(LOG_TAG, "StkAppService, getMainMenu, sim id: " + slotId); if (slotId >=0 && slotId < mSimCount && (mStkContext[slotId].mMainCmd != null)) { Menu menu = mStkContext[slotId].mMainCmd.getMenu(); - if (menu != null && mSimCount > PhoneConstants.MAX_PHONE_COUNT_SINGLE_SIM) { + if (menu != null) { // If alpha identifier or icon identifier with the self-explanatory qualifier is // specified in SET-UP MENU command, it should be more prioritized than preset ones. if (menu.title == null @@ -627,15 +626,7 @@ public class StkAppService extends Service implements Runnable { break; case OP_BOOT_COMPLETED: CatLog.d(LOG_TAG, " OP_BOOT_COMPLETED"); - int i = 0; - for (i = 0; i < mSimCount; i++) { - if (mStkContext[i].mMainCmd != null) { - break; - } - } - if (i == mSimCount) { - StkAppInstaller.unInstall(mContext); - } + uninstallIfUnnecessary(); break; case OP_DELAYED_MSG: handleDelayedCmd(slotId); @@ -736,9 +727,11 @@ public class StkAppService extends Service implements Runnable { == AppInterface.CommandType.PLAY_TONE.value()) { terminateTone(slotId); } + if (!uninstallIfUnnecessary()) { + addToMenuSystemOrUpdateLabel(); + } if (isAllOtherCardsAbsent(slotId)) { CatLog.d(LOG_TAG, "All CARDs are ABSENT"); - StkAppInstaller.unInstall(mContext); stopSelf(); } } else { @@ -841,7 +834,7 @@ public class StkAppService extends Service implements Runnable { }; CatLog.d(LOG_TAG, "Started to observe home key event"); registerReceiver(mHomeKeyEventReceiver, - new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); + new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), Context.RECEIVER_EXPORTED); } private synchronized void unregisterHomeKeyEventReceiver() { @@ -1088,13 +1081,6 @@ public class StkAppService extends Service implements Runnable { case DISPLAY_TEXT: TextMessage msg = cmdMsg.geTextMessage(); waitForUsersResponse = msg.responseNeeded; - if (mStkContext[slotId].lastSelectedItem != null) { - msg.title = mStkContext[slotId].lastSelectedItem; - } else if (mStkContext[slotId].mMainCmd != null){ - if (!getResources().getBoolean(R.bool.show_menu_title_only_on_menu)) { - msg.title = mStkContext[slotId].mMainCmd.getMenu().title; - } - } //If we receive a low priority Display Text and the device is // not displaying any STK related activity and the screen is not idle // ( that is, device is in an interactive state), then send a screen busy @@ -1127,24 +1113,14 @@ public class StkAppService extends Service implements Runnable { CatLog.d(LOG_TAG, "SET_UP_MENU [" + removeMenu(slotId) + "]"); if (removeMenu(slotId)) { - int i = 0; - CatLog.d(LOG_TAG, "removeMenu() - Uninstall App"); mStkContext[slotId].mCurrentMenu = null; mStkContext[slotId].mMainCmd = null; //Check other setup menu state. If all setup menu are removed, uninstall apk. - for (i = 0; i < mSimCount; i++) { - if (i != slotId && mStkContext[i].mSetupMenuState != STATE_NOT_EXIST) { - CatLog.d(LOG_TAG, "Not Uninstall App:" + i + "," - + mStkContext[i].mSetupMenuState); - break; - } - } - if (i == mSimCount) { - StkAppInstaller.unInstall(mContext); + if (!uninstallIfUnnecessary()) { + addToMenuSystemOrUpdateLabel(); } } else { - CatLog.d(LOG_TAG, "install App"); - StkAppInstaller.install(mContext); + addToMenuSystemOrUpdateLabel(); } if (mStkContext[slotId].mMenuIsVisible) { launchMenuActivity(null, slotId); @@ -1272,6 +1248,32 @@ public class StkAppService extends Service implements Runnable { } } + private void addToMenuSystemOrUpdateLabel() { + String candidateLabel = null; + + for (int slotId = 0; slotId < mSimCount; slotId++) { + Menu menu = getMainMenu(slotId); + if (menu != null) { + if (!TextUtils.isEmpty(candidateLabel)) { + if (!TextUtils.equals(menu.title, candidateLabel)) { + // We should not display the alpha identifier of SET-UP MENU command + // as the application label on the application launcher + // if different alpha identifiers are provided by multiple SIMs. + candidateLabel = null; + break; + } + } else { + if (TextUtils.isEmpty(menu.title)) { + break; + } + candidateLabel = menu.title; + } + } + } + + StkAppInstaller.installOrUpdate(this, candidateLabel); + } + @SuppressWarnings("FallThrough") private void handleCmdResponse(Bundle args, int slotId) { CatLog.d(LOG_TAG, "handleCmdResponse, sim id: " + slotId); @@ -1674,17 +1676,10 @@ public class StkAppService extends Service implements Runnable { private void launchNotificationOnKeyguard(int slotId, String message) { Notification.Builder builder = new Notification.Builder(this, STK_NOTIFICATION_CHANNEL_ID); + setNotificationTitle(slotId, builder); builder.setStyle(new Notification.BigTextStyle(builder).bigText(message)); builder.setContentText(message); - - Menu menu = getMainMenu(slotId); - if (menu == null || TextUtils.isEmpty(menu.title)) { - builder.setContentTitle(getResources().getString(R.string.app_name)); - } else { - builder.setContentTitle(menu.title); - } - builder.setSmallIcon(R.drawable.stat_notify_sim_toolkit); builder.setOngoing(true); builder.setOnlyAlertOnce(true); @@ -1848,8 +1843,8 @@ public class StkAppService extends Service implements Runnable { } private synchronized void registerHomeVisibilityObserver() { - if (mHomeVisibilityObserver == null) { - mHomeVisibilityObserver = new HomeVisibilityObserver() { + if (mHomeVisibilityListener == null) { + mHomeVisibilityListener = new HomeVisibilityListener() { @Override public void onHomeVisibilityChanged(boolean isHomeActivityVisible) { if (isHomeActivityVisible) { @@ -1860,7 +1855,7 @@ public class StkAppService extends Service implements Runnable { } }; ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE); - am.registerHomeVisibilityObserver(mHomeVisibilityObserver); + am.addHomeVisibilityListener(Runnable::run, mHomeVisibilityListener); CatLog.d(LOG_TAG, "Started to observe the foreground activity"); } } @@ -1892,11 +1887,11 @@ public class StkAppService extends Service implements Runnable { } private synchronized void unregisterHomeVisibilityObserver() { - if (mHomeVisibilityObserver != null) { + if (mHomeVisibilityListener != null) { ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE); - am.unregisterHomeVisibilityObserver(mHomeVisibilityObserver); + am.removeHomeVisibilityListener(mHomeVisibilityListener); CatLog.d(LOG_TAG, "Stopped to observe the foreground activity"); - mHomeVisibilityObserver = null; + mHomeVisibilityListener = null; } } @@ -2141,16 +2136,11 @@ public class StkAppService extends Service implements Runnable { + "] icon[" + msg.icon + "], sim id: " + slotId); CatLog.d(LOG_TAG, "Add IdleMode text"); PendingIntent pendingIntent = PendingIntent.getService(mContext, 0, - new Intent(mContext, StkAppService.class), 0); + new Intent(mContext, StkAppService.class), PendingIntent.FLAG_IMMUTABLE); createAllChannels(); final Notification.Builder notificationBuilder = new Notification.Builder( StkAppService.this, STK_NOTIFICATION_CHANNEL_ID); - if (mStkContext[slotId].mMainCmd != null && - mStkContext[slotId].mMainCmd.getMenu() != null) { - notificationBuilder.setContentTitle(mStkContext[slotId].mMainCmd.getMenu().title); - } else { - notificationBuilder.setContentTitle(""); - } + setNotificationTitle(slotId, notificationBuilder); notificationBuilder .setSmallIcon(R.drawable.stat_notify_sim_toolkit); notificationBuilder.setContentIntent(pendingIntent); @@ -2179,6 +2169,30 @@ public class StkAppService extends Service implements Runnable { } } + private void setNotificationTitle(int slotId, Notification.Builder builder) { + Menu menu = getMainMenu(slotId); + if (menu == null || TextUtils.isEmpty(menu.title) + || TextUtils.equals(menu.title, getResources().getString(R.string.app_name))) { + // No need to set a content title in the content area if no title (alpha identifier + // of SET-UP MENU command) is available for the specified slot or the title is same + // as the application label. + return; + } + + for (int index = 0; index < mSimCount; index++) { + if (index != slotId) { + Menu otherMenu = getMainMenu(index); + if (otherMenu != null && !TextUtils.equals(menu.title, otherMenu.title)) { + // Set the title (alpha identifier of SET-UP MENU command) as the content title + // to differentiate it from other main menu with different alpha identifier + // (including null) is available. + builder.setContentTitle(menu.title); + return; + } + } + } + } + /** Creates the notification channel and registers it with NotificationManager. * If a channel with the same ID is already registered, NotificationManager will * ignore this call. @@ -2327,6 +2341,10 @@ public class StkAppService extends Service implements Runnable { } } + boolean isNoTonePlaying() { + return mTonePlayer == null ? true : false; + } + private void launchOpenChannelDialog(final int slotId) { TextMessage msg = mStkContext[slotId].mCurrentCmd.geTextMessage(); if (msg == null) { @@ -2430,18 +2448,26 @@ public class StkAppService extends Service implements Runnable { try { if (mStkContext[slotId].mCurrentMenu.items.size() == 1 && mStkContext[slotId].mCurrentMenu.items.get(0) == null) { - mStkContext[slotId].mSetupMenuState = STATE_NOT_EXIST; return true; } } catch (NullPointerException e) { CatLog.d(LOG_TAG, "Unable to get Menu's items size"); - mStkContext[slotId].mSetupMenuState = STATE_NOT_EXIST; return true; } - mStkContext[slotId].mSetupMenuState = STATE_EXIST; return false; } + private boolean uninstallIfUnnecessary() { + for (int slot = 0; slot < mSimCount; slot++) { + if (mStkContext[slot].mMainCmd != null) { + return false; + } + } + CatLog.d(LOG_TAG, "Uninstall App"); + StkAppInstaller.uninstall(this); + return true; + } + synchronized StkContext getStkContext(int slotId) { if (slotId >= 0 && slotId < mSimCount) { return mStkContext[slotId]; diff --git a/src/com/android/stk/StkInputActivity.java b/src/com/android/stk/StkInputActivity.java index 0af6767..b9c821b 100644 --- a/src/com/android/stk/StkInputActivity.java +++ b/src/com/android/stk/StkInputActivity.java @@ -452,7 +452,9 @@ public class StkInputActivity extends AppCompatActivity implements View.OnClickL } textInput.setHelperText(getResources().getString(inTypeId)); textInput.setHelperTextEnabled(!hideHelper); - + CatLog.d(LOG_TAG, + String.format("configInputDisplay: digitOnly=%s, hideHelper=%s", + mStkInput.digitOnly, hideHelper)); setTitle(R.string.app_name); if (mStkInput.icon != null) { @@ -467,7 +469,8 @@ public class StkInputActivity extends AppCompatActivity implements View.OnClickL mTextIn.setFilters(new InputFilter[] {new InputFilter.LengthFilter(mStkInput.maxLen)}); textInput.setCounterMaxLength(mStkInput.maxLen); - textInput.setCounterEnabled(true); + //do not show the length helper for the text input + textInput.setCounterEnabled(false); if (!mStkInput.echo) { mTextIn.setTransformationMethod(PasswordTransformationMethod diff --git a/src/com/android/stk/ToneDialog.java b/src/com/android/stk/ToneDialog.java index 2efeecd..417c8eb 100644 --- a/src/com/android/stk/ToneDialog.java +++ b/src/com/android/stk/ToneDialog.java @@ -55,7 +55,7 @@ public class ToneDialog extends Activity { // Register receiver IntentFilter filter = new IntentFilter(); filter.addAction(StkAppService.FINISH_TONE_ACTIVITY_ACTION); - registerReceiver(mFinishActivityReceiver, filter); + registerReceiver(mFinishActivityReceiver, filter, Context.RECEIVER_NOT_EXPORTED); AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this); LayoutInflater inflater = this.getLayoutInflater(); @@ -92,6 +92,12 @@ public class ToneDialog extends Activity { mAlertDialog = alertDialogBuilder.create(); mAlertDialog.show(); + + StkAppService appService = StkAppService.getInstance(); + // Finish the activity if the specified duration is too short and timed-out already. + if (appService != null && (appService.isNoTonePlaying())) { + finish(); + } } @Override |