OSDN Git Service

Settings: Fix possible NPE
[android-x86/packages-apps-Settings.git] / src / com / android / settings / applications / InstalledAppDetails.java
index 824cd18..ef3788c 100755 (executable)
@@ -28,6 +28,7 @@ import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.Loader;
+import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
@@ -63,6 +64,7 @@ import android.view.ViewGroup;
 import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.TextView;
+import com.android.settings.cyanogenmod.ProtectedAppsReceiver;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.os.BatterySipper;
@@ -106,10 +108,12 @@ public class InstalledAppDetails extends AppInfoBase
     // Menu identifiers
     public static final int UNINSTALL_ALL_USERS_MENU = 1;
     public static final int UNINSTALL_UPDATES = 2;
+    public static final int OPEN_PROTECTED_APPS = 3;
 
     // Result code identifiers
     public static final int REQUEST_UNINSTALL = 0;
     private static final int SUB_INFO_FRAGMENT = 1;
+    public static final int REQUEST_TOGGLE_PROTECTION = 3;
 
     private static final int LOADER_CHART_DATA = 2;
 
@@ -236,6 +240,12 @@ public class InstalledAppDetails extends AppInfoBase
             enabled = false;
         }
 
+        // This is a protected app component.
+        // You cannot a uninstall a protected component
+        if (mPackageInfo.applicationInfo.protect) {
+            enabled = false;
+        }
+
         mUninstallButton.setEnabled(enabled);
         if (enabled) {
             // Register listener
@@ -375,6 +385,9 @@ public class InstalledAppDetails extends AppInfoBase
                 .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
         menu.add(0, UNINSTALL_ALL_USERS_MENU, 1, R.string.uninstall_all_users_text)
                 .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+        menu.add(0, OPEN_PROTECTED_APPS, Menu.NONE, R.string.protected_apps)
+                .setIcon(getResources().getDrawable(R.drawable.folder_lock))
+                .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
     }
 
     @Override
@@ -399,6 +412,9 @@ public class InstalledAppDetails extends AppInfoBase
         menu.findItem(UNINSTALL_ALL_USERS_MENU).setVisible(showIt);
         mUpdatedSysApp = (mAppEntry.info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
         menu.findItem(UNINSTALL_UPDATES).setVisible(mUpdatedSysApp && !mAppControlRestricted);
+
+        menu.findItem(OPEN_PROTECTED_APPS).setVisible(mPackageInfo != null &&
+                mPackageInfo.applicationInfo != null && mPackageInfo.applicationInfo.protect);
     }
 
     @Override
@@ -410,6 +426,10 @@ public class InstalledAppDetails extends AppInfoBase
             case UNINSTALL_UPDATES:
                 showDialogInner(DLG_FACTORY_RESET, 0);
                 return true;
+            case OPEN_PROTECTED_APPS:
+                // Verify protection for toggling protected component status
+                Intent protectedApps = new Intent(getActivity(), LockPatternActivity.class);
+                startActivityForResult(protectedApps, REQUEST_TOGGLE_PROTECTION);
         }
         return false;
     }
@@ -435,6 +455,37 @@ public class InstalledAppDetails extends AppInfoBase
             if (!refreshUi()) {
                 setIntentAndFinish(true, true);
             }
+        } else if (requestCode == REQUEST_TOGGLE_PROTECTION) {
+            switch (resultCode) {
+                case Activity.RESULT_OK:
+                    new ToggleProtectedAppComponents().execute();
+                    break;
+                case Activity.RESULT_CANCELED:
+                    // User failed to enter/confirm a lock pattern, do nothing
+                    break;
+            }
+        }
+    }
+
+    private class ToggleProtectedAppComponents extends AsyncTask<Void, Void, Void> {
+        @Override
+        protected void onPostExecute(Void aVoid) {
+            getActivity().invalidateOptionsMenu();
+            if (!refreshUi()) {
+                setIntentAndFinish(true, true);
+            }
+        }
+
+        @Override
+        protected Void doInBackground(Void... params) {
+            ArrayList<ComponentName> components = new ArrayList<ComponentName>();
+            for (ActivityInfo aInfo : mPackageInfo.activities) {
+                components.add(new ComponentName(aInfo.packageName, aInfo.name));
+            }
+
+            ProtectedAppsReceiver.updateProtectedAppComponentsAndNotify(getActivity(),
+                    components, PackageManager.COMPONENT_VISIBLE_STATUS);
+            return null;
         }
     }
 
@@ -443,7 +494,7 @@ public class InstalledAppDetails extends AppInfoBase
         final View appSnippet = mHeader.findViewById(R.id.app_snippet);
         mState.ensureIcon(mAppEntry);
         setupAppSnippet(appSnippet, mAppEntry.label, mAppEntry.icon,
-                pkgInfo != null ? pkgInfo.versionName : null);
+                pkgInfo != null ? pkgInfo.versionName : null, pkgInfo.packageName);
     }
 
     private boolean signaturesMatch(String pkg1, String pkg2) {
@@ -658,6 +709,10 @@ public class InstalledAppDetails extends AppInfoBase
     }
 
     private void checkForceStop() {
+        if (getActivity() == null || getActivity().isFinishing()) {
+            return;
+        }
+
         if (mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) {
             // User can't force stop device admin.
             updateForceStopButton(false);
@@ -766,7 +821,7 @@ public class InstalledAppDetails extends AppInfoBase
     }
 
     public static void setupAppSnippet(View appSnippet, CharSequence label, Drawable icon,
-            CharSequence versionName) {
+            CharSequence versionName, String packageName) {
         LayoutInflater.from(appSnippet.getContext()).inflate(R.layout.widget_text_views,
                 (ViewGroup) appSnippet.findViewById(android.R.id.widget_frame));
 
@@ -778,6 +833,12 @@ public class InstalledAppDetails extends AppInfoBase
         // Version number of application
         TextView appVersion = (TextView) appSnippet.findViewById(R.id.widget_text1);
 
+        if (packageName != null) {
+            TextView appPackage = (TextView) appSnippet.findViewById(R.id.widget_text2);
+            appPackage.setText(packageName);
+            appPackage.setSelected(true);
+        }
+
         if (!TextUtils.isEmpty(versionName)) {
             appVersion.setSelected(true);
             appVersion.setVisibility(View.VISIBLE);
@@ -927,6 +988,13 @@ public class InstalledAppDetails extends AppInfoBase
             mPm.setApplicationEnabledSetting(mInfo.packageName, mState, 0);
             return null;
         }
+
+        @Override
+        protected void onPostExecute(Object o) {
+            if (mActivity.get() !=  null) {
+                mActivity.get().refreshUi();
+            }
+        }
     }
 
     private final LoaderCallbacks<ChartData> mDataCallbacks = new LoaderCallbacks<ChartData>() {
@@ -951,7 +1019,9 @@ public class InstalledAppDetails extends AppInfoBase
     private final BroadcastReceiver mCheckKillProcessesReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            updateForceStopButton(getResultCode() != Activity.RESULT_CANCELED);
+            if (getActivity() != null && !getActivity().isDestroyed()) {
+                updateForceStopButton(getResultCode() != Activity.RESULT_CANCELED);
+            }
         }
     };