165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane/*
265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Copyright (C) 2014 The Android Open Source Project
365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane *
465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Licensed under the Apache License, Version 2.0 (the "License");
565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * you may not use this file except in compliance with the License.
665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * You may obtain a copy of the License at
765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane *
865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane *      http://www.apache.org/licenses/LICENSE-2.0
965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane *
1065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Unless required by applicable law or agreed to in writing, software
1165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * distributed under the License is distributed on an "AS IS" BASIS,
1265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * See the License for the specific language governing permissions and
1465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * limitations under the License.
1565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */
1665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
1765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lanepackage com.android.tv.settings.users;
1865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
1965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.R;
2065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.dialog.DialogFragment;
2165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.dialog.DialogFragment.Action;
2265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.users.AppRestrictionsManager.Listener;
2365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
2465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.app.Activity;
2565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.app.Fragment;
2665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.BroadcastReceiver;
2765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.Context;
2865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.Intent;
2965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.IntentFilter;
3065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.RestrictionEntry;
3165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.pm.ApplicationInfo;
3265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.pm.IPackageManager;
3365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.pm.PackageManager;
3465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.pm.UserInfo;
3565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.pm.PackageManager.NameNotFoundException;
3665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.net.Uri;
3765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.AsyncTask;
3865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.Bundle;
3965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.RemoteException;
4065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.ServiceManager;
4165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.UserHandle;
4265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.UserManager;
4365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.util.Log;
4465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
4565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.util.ArrayList;
4665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.util.HashMap;
4765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.util.Map;
4865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
4965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane/**
5065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * DialogFragment that configures the app restrictions for a given user.
5165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */
5265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lanepublic class UserAppRestrictionsDialogFragment extends DialogFragment implements Action.Listener,
5365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        AppLoadingTask.Listener {
5465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
5565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private static final boolean DEBUG = false;
5665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private static final String TAG = "RestrictedProfile";
5765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
5865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    /** Key for extra passed in from calling fragment for the userId of the user being edited */
5965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    public static final String EXTRA_USER_ID = "user_id";
6065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
6165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    /** Key for extra passed in from calling fragment to indicate if this is a newly created user */
6265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    public static final String EXTRA_NEW_USER = "new_user";
6365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
6465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private static final String EXTRA_CONTENT_TITLE = "title";
6565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private static final String EXTRA_CONTENT_BREADCRUMB = "breadcrumb";
6665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private static final String EXTRA_CONTENT_DESCRIPTION = "description";
6765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private static final String EXTRA_CONTENT_ICON_RESOURCE_ID = "iconResourceId";
6865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private static final String EXTRA_CONTENT_ICON_URI = "iconUri";
6965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private static final String EXTRA_CONTENT_ICON_BITMAP = "iconBitmap";
7065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private static final String EXTRA_CONTENT_ICON_BACKGROUND = "iconBackground";
7165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
7265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private static final String EXTRA_PACKAGE_NAME = "packageName";
7365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private static final String EXTRA_CAN_CONFIGURE_RESTRICTIONS = "canConfigureRestrictions";
7465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private static final String EXTRA_CAN_SEE_RESTRICTED_ACCOUNTS = "canSeeRectrictedAccounts";
7565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private static final String EXTRA_IS_ALLOWED = "isAllowed";
7665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private static final String EXTRA_CAN_BE_ENABLED_DISABLED = "canBeEnabledDisabled";
7765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private static final String EXTRA_CONTROLLING_APP = "controllingApp";
7865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
7965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private static final String ACTION_ALLOW = "allow";
8065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private static final String ACTION_DISALLOW = "disallow";
8165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private static final String ACTION_CONFIGURE = "configure";
8265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private static final String ACTION_CUSTOMIZE_RESTRICTIONS = "customizeRestriction";
8365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
8465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private static final int CHECK_SET_ID = 1;
8565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
8665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    public static UserAppRestrictionsDialogFragment newInstance(Context context, int userId,
8765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            boolean newUser) {
8865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        UserAppRestrictionsDialogFragment fragment = new UserAppRestrictionsDialogFragment();
8965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        Bundle args = new Bundle();
9065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        args.putString(EXTRA_CONTENT_TITLE,
9165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                context.getString(R.string.restricted_profile_configure_apps_title));
9265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        args.putInt(EXTRA_CONTENT_ICON_RESOURCE_ID, R.drawable.ic_settings_launcher_icon);
9365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        args.putInt(EXTRA_CONTENT_ICON_BACKGROUND,
9465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                context.getResources().getColor(R.color.icon_background));
9565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        args.putInt(EXTRA_USER_ID, userId);
9665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        args.putBoolean(EXTRA_NEW_USER, newUser);
9765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        fragment.setArguments(args);
9865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        return fragment;
9965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
10065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
10165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private UserManager mUserManager;
10265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private IPackageManager mIPm;
10365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private AppLoadingTask mAppLoadingTask;
10465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private final HashMap<String, Boolean> mSelectedPackages = new HashMap<String, Boolean>();
10565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private UserHandle mUser;
10665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private boolean mNewUser;
10765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private boolean mAppListChanged;
10865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private AppRestrictionsManager mAppRestrictionsManager;
10965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
11065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private BroadcastReceiver mUserBackgrounding = new BroadcastReceiver() {
11165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        @Override
11265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        public void onReceive(Context context, Intent intent) {
11365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            // Update the user's app selection right away without waiting for a pause
11465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            // onPause() might come in too late, causing apps to disappear after broadcasts
11565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            // have been scheduled during user startup.
11665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            if (mAppListChanged) {
11765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                if (DEBUG) {
11865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                    Log.d(TAG, "User backgrounding, update app list");
11965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                }
12065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                applyUserAppsStates(mSelectedPackages, getActions(), mIPm, mUser.getIdentifier());
12165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                if (DEBUG) {
12265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                    Log.d(TAG, "User backgrounding, done updating app list");
12365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                }
12465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            }
12565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        }
12665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    };
12765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private BroadcastReceiver mPackageObserver = new BroadcastReceiver() {
12865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        @Override
12965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        public void onReceive(Context context, Intent intent) {
13065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            onPackageChanged(intent);
13165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        }
13265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
13365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        private void onPackageChanged(Intent intent) {
13465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            String action = intent.getAction();
13565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            String packageName = intent.getData().getSchemeSpecificPart();
13665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            // Package added, check if the preference needs to be enabled
13765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            ArrayList<Action> matchingActions = findActionsWithPackageName(getActions(),
13865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                    packageName);
13965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            for (Action matchingAction : matchingActions) {
14065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                if ((Intent.ACTION_PACKAGE_ADDED.equals(action) && matchingAction.isChecked()) || (
14165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        Intent.ACTION_PACKAGE_REMOVED.equals(action)
14265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        && !matchingAction.isChecked())) {
14365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                    matchingAction.setEnabled(true);
14465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                }
14565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            }
14665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        }
14765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    };
14865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
14965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    @Override
15065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    public void onCreate(Bundle icicle) {
15165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        super.onCreate(icicle);
15265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        mUserManager = (UserManager) getActivity().getSystemService(Context.USER_SERVICE);
15365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        setActions(new ArrayList<Action>());
15465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        setListener(this);
15565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        if (icicle != null) {
15665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            mUser = new UserHandle(icicle.getInt(EXTRA_USER_ID));
15765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        } else {
15865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            Bundle args = getArguments();
15965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            if (args != null) {
16065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                if (args.containsKey(EXTRA_USER_ID)) {
16165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                    mUser = new UserHandle(args.getInt(EXTRA_USER_ID));
16265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                }
16365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                mNewUser = args.getBoolean(EXTRA_NEW_USER, false);
16465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            }
16565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        }
16665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
16765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        if (mUser == null) {
16865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            mUser = android.os.Process.myUserHandle();
16965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        }
17065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
17165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        mIPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
17265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
17365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
17465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    @Override
17565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    public void onResume() {
17665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        super.onResume();
17765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
17865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        getActivity().registerReceiver(mUserBackgrounding,
17965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                new IntentFilter(Intent.ACTION_USER_BACKGROUND));
18065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        IntentFilter packageFilter = new IntentFilter();
18165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
18265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
18365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        packageFilter.addDataScheme("package");
18465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        getActivity().registerReceiver(mPackageObserver, packageFilter);
18565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
18665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        if (mAppLoadingTask == null) {
18765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            mAppListChanged = false;
18865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            mAppLoadingTask = new AppLoadingTask(getActivity(), mUser.getIdentifier(), mNewUser,
18965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                    mIPm, this);
19065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            mAppLoadingTask.execute((Void[]) null);
19165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        }
19265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
19365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
19465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    @Override
19565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    public void onPause() {
19665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        super.onPause();
19765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        mNewUser = false;
19865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        getActivity().unregisterReceiver(mUserBackgrounding);
19965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        getActivity().unregisterReceiver(mPackageObserver);
20065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        if (mAppListChanged) {
20165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            new Thread() {
20265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                public void run() {
20365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                    applyUserAppsStates(mSelectedPackages, getActions(), mIPm,
20465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                            mUser.getIdentifier());
20565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                }
20665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            }.start();
20765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        }
20865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
20965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
21065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    @Override
21165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    public void onActionClicked(Action action) {
21265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        String packageName = action.getIntent().getStringExtra(EXTRA_PACKAGE_NAME);
21365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        if (ACTION_CONFIGURE.equals(action.getKey())) {
21465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            boolean isAllowed = action.getIntent().getBooleanExtra(EXTRA_IS_ALLOWED, false);
21565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            boolean canBeEnabledDisabled = action.getIntent().getBooleanExtra(
21665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                    EXTRA_CAN_BE_ENABLED_DISABLED, false);
21765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            String controllingActivity = action.getIntent().getStringExtra(EXTRA_CONTROLLING_APP);
21865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            final ArrayList<Action> initialAllowDisallowActions = new ArrayList<Action>();
21965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            if (controllingActivity != null) {
22065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                initialAllowDisallowActions.add(new Action.Builder()
22165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        .title(getString(isAllowed ? R.string.restricted_profile_allowed
22265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                                : R.string.restricted_profile_not_allowed))
22365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        .description(getString(R.string.user_restrictions_controlled_by,
22465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                                controllingActivity))
22565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        .checked(isAllowed)
22665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        .infoOnly(true)
22765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        .build());
22865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            } else if (!canBeEnabledDisabled) {
22965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                initialAllowDisallowActions.add(new Action.Builder()
23065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        .title(getString(isAllowed ? R.string.restricted_profile_allowed
23165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                                : R.string.restricted_profile_not_allowed))
23265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        .checked(isAllowed)
23365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        .infoOnly(true)
23465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        .build());
23565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            } else {
23665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                boolean canSeeRestrictedAccounts = action.getIntent().getBooleanExtra(
23765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        EXTRA_CAN_SEE_RESTRICTED_ACCOUNTS, true);
23865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                initialAllowDisallowActions.add(new Action.Builder().key(ACTION_DISALLOW)
23965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        .title(getString(R.string.restricted_profile_not_allowed))
24065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        .intent(action.getIntent())
24165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        .checked(!isAllowed)
24265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        .checkSetId(CHECK_SET_ID).build());
24365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                initialAllowDisallowActions.add(new Action.Builder().key(ACTION_ALLOW)
24465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        .title(getString(R.string.restricted_profile_allowed))
24565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        .description(canSeeRestrictedAccounts ? getString(
24665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                                R.string.app_sees_restricted_accounts)
24765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                                : null)
24865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        .intent(action.getIntent())
24965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        .checkSetId(CHECK_SET_ID)
25065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        .checked(isAllowed)
25165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        .build());
25265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            }
25365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
25465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            final DialogFragment dialogFragment = new DialogFragment.Builder()
25565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                    .title(action.getTitle()).iconUri(action.getIconUri())
25665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                    .actions(initialAllowDisallowActions).build();
25765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
25865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            boolean canConfigureRestrictions = action.getIntent().getBooleanExtra(
25965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                    EXTRA_CAN_CONFIGURE_RESTRICTIONS, false);
26065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            if (canConfigureRestrictions) {
26165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                mAppRestrictionsManager = new AppRestrictionsManager(this, mUser,
26265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        mUserManager, packageName, new AppRestrictionsManager.Listener() {
26365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                            @Override
26465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                            public void onRestrictionActionsLoaded(String packageName,
26565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                                    ArrayList<Action> restrictionActions) {
26665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                                ArrayList<Action> oldActions = dialogFragment.getActions();
26765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                                ArrayList<Action> newActions = new ArrayList<Action>();
26865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                                if (oldActions != null && oldActions.size()
26965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                                        >= initialAllowDisallowActions.size()) {
27065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                                    for (int i = 0, size = initialAllowDisallowActions.size();
27165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                                            i < size; i++) {
27265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                                        newActions.add(oldActions.get(i));
27365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                                    }
27465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                                } else {
27565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                                    newActions.addAll(initialAllowDisallowActions);
27665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                                }
27765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                                newActions.addAll(restrictionActions);
27865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                                dialogFragment.setActions(newActions);
27965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                            }
28065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        });
28165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                mAppRestrictionsManager.loadRestrictionActions();
28265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            }
28365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
28465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            dialogFragment.setListener(this);
28565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            DialogFragment.add(getFragmentManager(), dialogFragment);
28665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        } else if (ACTION_ALLOW.equals(action.getKey())) {
28765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            setEnabled(packageName, true);
28865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        } else if (ACTION_DISALLOW.equals(action.getKey())) {
28965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            setEnabled(packageName, false);
29065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        } else if (mAppRestrictionsManager != null) {
29165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            mAppRestrictionsManager.onActionClicked(action);
29265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        }
29365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
29465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
29565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    @Override
29665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    public void onActivityResult(int requestCode, int resultCode, Intent data) {
29765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        if (mAppRestrictionsManager != null) {
29865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            mAppRestrictionsManager.onActivityResult(requestCode, resultCode, data);
29965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        }
30065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
30165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
30265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private void setEnabled(String packageName, boolean enabled) {
30365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        onPackageEnableChanged(packageName, enabled);
30465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        for (Action action : getActions()) {
30565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            String actionPackageName = action.getIntent().getStringExtra(EXTRA_PACKAGE_NAME);
30665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            if (actionPackageName.equals(packageName)) {
30765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                action.setChecked(enabled);
30865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                action.setDescription(getString(enabled ? R.string.restricted_profile_allowed
30965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        : R.string.restricted_profile_not_allowed));
31065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                action.getIntent().putExtra(EXTRA_IS_ALLOWED, enabled);
31165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            }
31265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        }
31365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        onActionsLoaded(getActions());
31465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
31565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
31665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    @Override
31765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    public void onPackageEnableChanged(String packageName, boolean enabled) {
31865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        mSelectedPackages.put(packageName, enabled);
31965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        mAppListChanged = true;
32065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        if (getActivity() instanceof AppLoadingTask.Listener) {
32165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            ((AppLoadingTask.Listener) getActivity()).onPackageEnableChanged(packageName, enabled);
32265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        }
32365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
32465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
32565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    @Override
32665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    public void onActionsLoaded(ArrayList<Action> actions) {
32765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        setActions(actions);
32865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        if (getActivity() instanceof AppLoadingTask.Listener) {
32965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            ((AppLoadingTask.Listener) getActivity()).onActionsLoaded(actions);
33065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        }
33165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
33265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
33365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    static Action createAction(Context context, String packageName, String title, Uri iconUri,
33465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            boolean canBeEnabledDisabled, boolean isAllowed, boolean hasCustomizableRestrictions,
33565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            boolean canSeeRestrictedAccounts, boolean availableForRestrictedProfile,
33665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            String controllingActivity) {
33765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        String description = context.getString(
33865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                availableForRestrictedProfile ? isAllowed ? R.string.restricted_profile_allowed
33965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        : R.string.restricted_profile_not_allowed
34065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        : R.string.app_not_supported_in_limited);
34165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
34265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        Intent intent = new Intent().putExtra(EXTRA_IS_ALLOWED, isAllowed)
34365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                .putExtra(EXTRA_CAN_CONFIGURE_RESTRICTIONS,
34465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        (hasCustomizableRestrictions && (controllingActivity == null)))
34565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                .putExtra(EXTRA_CAN_BE_ENABLED_DISABLED, canBeEnabledDisabled)
34665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                .putExtra(EXTRA_PACKAGE_NAME, packageName)
34765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                .putExtra(EXTRA_CONTROLLING_APP, controllingActivity)
34865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                .putExtra(EXTRA_CAN_SEE_RESTRICTED_ACCOUNTS, canSeeRestrictedAccounts);
34965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
35065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        if (DEBUG) {
35165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            Log.d(TAG, "Icon uri: " + (iconUri != null ? iconUri.toString() : "null"));
35265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        }
35365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        return new Action.Builder()
35465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                .key(ACTION_CONFIGURE)
35565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                .title(title)
35665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                .description(description)
35765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                .enabled(availableForRestrictedProfile)
35865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                .iconUri(iconUri)
35965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                .checked(isAllowed)
36065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                .intent(intent)
36165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                .build();
36265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
36365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
36465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    static void applyUserAppsStates(HashMap<String, Boolean> selectedPackages,
36565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            ArrayList<Action> actions, IPackageManager ipm, int userId) {
36665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        for (Map.Entry<String, Boolean> entry : selectedPackages.entrySet()) {
36765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            String packageName = entry.getKey();
36865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            boolean enabled = entry.getValue();
36965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            if (applyUserAppState(ipm, userId, packageName, enabled)) {
37065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                disableActionForPackage(actions, packageName);
37165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            }
37265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        }
37365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
37465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
37565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    static boolean applyUserAppState(IPackageManager ipm, int userId, String packageName,
37665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            boolean enabled) {
37765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        boolean disableActionForPackage = false;
37865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        if (enabled) {
37965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            // Enable selected apps
38065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            try {
38165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                ApplicationInfo info = ipm.getApplicationInfo(packageName,
38265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        PackageManager.GET_UNINSTALLED_PACKAGES, userId);
38365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                if (info == null || info.enabled == false
38465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        || (info.flags & ApplicationInfo.FLAG_INSTALLED) == 0) {
38565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                    ipm.installExistingPackageAsUser(packageName, userId);
38665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                    if (DEBUG) {
38765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        Log.d(TAG, "Installing " + packageName);
38865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                    }
38965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                }
39065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                if (info != null && (info.flags & ApplicationInfo.FLAG_HIDDEN) != 0
39165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        && (info.flags & ApplicationInfo.FLAG_INSTALLED) != 0) {
39265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                    disableActionForPackage = true;
39365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                    ipm.setApplicationHiddenSettingAsUser(packageName, false, userId);
39465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                    if (DEBUG) {
39565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        Log.d(TAG, "Unhiding " + packageName);
39665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                    }
39765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                }
39865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            } catch (RemoteException re) {
39965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                Log.e(TAG, "Caught exception while installing " + packageName + "!", re);
40065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            }
40165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        } else {
40265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            // Blacklist all other apps, system or downloaded
40365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            try {
40465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                ApplicationInfo info = ipm.getApplicationInfo(packageName, 0, userId);
40565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                if (info != null) {
40665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                    ipm.deletePackageAsUser(packageName, null, userId,
40765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                            PackageManager.DELETE_SYSTEM_APP);
40865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                    if (DEBUG) {
40965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                        Log.d(TAG, "Uninstalling " + packageName);
41065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                    }
41165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                }
41265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            } catch (RemoteException re) {
41365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                Log.e(TAG, "Caught exception while uninstalling " + packageName + "!", re);
41465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            }
41565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        }
41665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        return disableActionForPackage;
41765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
41865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
41965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private static void disableActionForPackage(ArrayList<Action> actions, String packageName) {
42065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        ArrayList<Action> matchingActions = findActionsWithPackageName(actions, packageName);
42165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        for(Action matchingAction : matchingActions) {
42265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            matchingAction.setEnabled(false);
42365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        }
42465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
42565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane
42665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    private static ArrayList<Action> findActionsWithPackageName(ArrayList<Action> actions,
42765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            String packageName) {
42865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        ArrayList<Action> matchingActions = new ArrayList<Action>();
42965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        if (packageName != null) {
43065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            for (Action action : actions) {
43165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                if (packageName.equals(action.getIntent().getStringExtra(EXTRA_PACKAGE_NAME))) {
43265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                    matchingActions.add(action);
43365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane                }
43465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane            }
43565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        }
43665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane        return matchingActions;
43765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane    }
43865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane}
439