1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.applications; 18 19 import android.app.Activity; 20 import android.app.AlertDialog; 21 import android.app.Dialog; 22 import android.app.DialogFragment; 23 import android.app.Fragment; 24 import android.app.admin.DevicePolicyManager; 25 import android.content.Context; 26 import android.content.Intent; 27 import android.content.pm.PackageInfo; 28 import android.content.pm.PackageManager; 29 import android.content.pm.PackageManager.NameNotFoundException; 30 import android.hardware.usb.IUsbManager; 31 import android.os.Bundle; 32 import android.os.IBinder; 33 import android.os.ServiceManager; 34 import android.os.UserHandle; 35 import android.os.UserManager; 36 import android.util.Log; 37 38 import com.android.settings.SettingsActivity; 39 import com.android.settings.SettingsPreferenceFragment; 40 import com.android.settings.Utils; 41 import com.android.settingslib.RestrictedLockUtils; 42 import com.android.settingslib.applications.ApplicationsState; 43 import com.android.settingslib.applications.ApplicationsState.AppEntry; 44 45 import java.util.ArrayList; 46 47 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; 48 49 public abstract class AppInfoBase extends SettingsPreferenceFragment 50 implements ApplicationsState.Callbacks { 51 52 public static final String ARG_PACKAGE_NAME = "package"; 53 public static final String ARG_PACKAGE_UID = "uid"; 54 55 protected static final String TAG = AppInfoBase.class.getSimpleName(); 56 protected static final boolean localLOGV = false; 57 58 protected EnforcedAdmin mAppsControlDisallowedAdmin; 59 protected boolean mAppsControlDisallowedBySystem; 60 61 protected ApplicationsState mState; 62 protected ApplicationsState.Session mSession; 63 protected ApplicationsState.AppEntry mAppEntry; 64 protected PackageInfo mPackageInfo; 65 protected int mUserId; 66 protected String mPackageName; 67 68 protected IUsbManager mUsbManager; 69 protected DevicePolicyManager mDpm; 70 protected UserManager mUserManager; 71 protected PackageManager mPm; 72 73 // Dialog identifiers used in showDialog 74 protected static final int DLG_BASE = 0; 75 76 protected boolean mFinishing; 77 78 @Override 79 public void onCreate(Bundle savedInstanceState) { 80 super.onCreate(savedInstanceState); 81 mFinishing = false; 82 83 mState = ApplicationsState.getInstance(getActivity().getApplication()); 84 mSession = mState.newSession(this); 85 Context context = getActivity(); 86 mDpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE); 87 mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); 88 mPm = context.getPackageManager(); 89 IBinder b = ServiceManager.getService(Context.USB_SERVICE); 90 mUsbManager = IUsbManager.Stub.asInterface(b); 91 92 retrieveAppEntry(); 93 } 94 95 @Override 96 public void onResume() { 97 super.onResume(); 98 mSession.resume(); 99 mAppsControlDisallowedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(getActivity(), 100 UserManager.DISALLOW_APPS_CONTROL, mUserId); 101 mAppsControlDisallowedBySystem = RestrictedLockUtils.hasBaseUserRestriction(getActivity(), 102 UserManager.DISALLOW_APPS_CONTROL, mUserId); 103 104 if (!refreshUi()) { 105 setIntentAndFinish(true, true); 106 } 107 } 108 109 @Override 110 public void onPause() { 111 mSession.pause(); 112 super.onPause(); 113 } 114 115 @Override 116 public void onDestroy() { 117 mSession.release(); 118 super.onDestroy(); 119 } 120 121 protected String retrieveAppEntry() { 122 final Bundle args = getArguments(); 123 mPackageName = (args != null) ? args.getString(ARG_PACKAGE_NAME) : null; 124 if (mPackageName == null) { 125 Intent intent = (args == null) ? 126 getActivity().getIntent() : (Intent) args.getParcelable("intent"); 127 if (intent != null) { 128 mPackageName = intent.getData().getSchemeSpecificPart(); 129 } 130 } 131 mUserId = UserHandle.myUserId(); 132 mAppEntry = mState.getEntry(mPackageName, mUserId); 133 if (mAppEntry != null) { 134 // Get application info again to refresh changed properties of application 135 try { 136 mPackageInfo = mPm.getPackageInfo(mAppEntry.info.packageName, 137 PackageManager.GET_DISABLED_COMPONENTS | 138 PackageManager.GET_UNINSTALLED_PACKAGES | 139 PackageManager.GET_SIGNATURES | 140 PackageManager.GET_PERMISSIONS); 141 } catch (NameNotFoundException e) { 142 Log.e(TAG, "Exception when retrieving package:" + mAppEntry.info.packageName, e); 143 } 144 } else { 145 Log.w(TAG, "Missing AppEntry; maybe reinstalling?"); 146 mPackageInfo = null; 147 } 148 149 return mPackageName; 150 } 151 152 protected void setIntentAndFinish(boolean finish, boolean appChanged) { 153 if (localLOGV) Log.i(TAG, "appChanged="+appChanged); 154 Intent intent = new Intent(); 155 intent.putExtra(ManageApplications.APP_CHG, appChanged); 156 SettingsActivity sa = (SettingsActivity)getActivity(); 157 sa.finishPreferencePanel(this, Activity.RESULT_OK, intent); 158 mFinishing = true; 159 } 160 161 protected void showDialogInner(int id, int moveErrorCode) { 162 DialogFragment newFragment = MyAlertDialogFragment.newInstance(id, moveErrorCode); 163 newFragment.setTargetFragment(this, 0); 164 newFragment.show(getFragmentManager(), "dialog " + id); 165 } 166 167 protected abstract boolean refreshUi(); 168 protected abstract AlertDialog createDialog(int id, int errorCode); 169 170 @Override 171 public void onRunningStateChanged(boolean running) { 172 // No op. 173 } 174 175 @Override 176 public void onRebuildComplete(ArrayList<AppEntry> apps) { 177 // No op. 178 } 179 180 @Override 181 public void onPackageIconChanged() { 182 // No op. 183 } 184 185 @Override 186 public void onPackageSizeChanged(String packageName) { 187 // No op. 188 } 189 190 @Override 191 public void onAllSizesComputed() { 192 // No op. 193 } 194 195 @Override 196 public void onLauncherInfoChanged() { 197 // No op. 198 } 199 200 @Override 201 public void onLoadEntriesCompleted() { 202 // No op. 203 } 204 205 @Override 206 public void onPackageListChanged() { 207 refreshUi(); 208 } 209 210 public static void startAppInfoFragment(Class<?> fragment, int titleRes, 211 String pkg, int uid, Fragment source, int request) { 212 startAppInfoFragment(fragment, titleRes, pkg, uid, source.getActivity(), request); 213 } 214 215 public static void startAppInfoFragment(Class<?> fragment, int titleRes, 216 String pkg, int uid, Activity source, int request) { 217 Bundle args = new Bundle(); 218 args.putString(AppInfoBase.ARG_PACKAGE_NAME, pkg); 219 args.putInt(AppInfoBase.ARG_PACKAGE_UID, uid); 220 221 Intent intent = Utils.onBuildStartFragmentIntent(source, fragment.getName(), 222 args, null, titleRes, null, false); 223 source.startActivityForResultAsUser(intent, request, 224 new UserHandle(UserHandle.getUserId(uid))); 225 } 226 227 public static class MyAlertDialogFragment extends DialogFragment { 228 229 @Override 230 public Dialog onCreateDialog(Bundle savedInstanceState) { 231 int id = getArguments().getInt("id"); 232 int errorCode = getArguments().getInt("moveError"); 233 Dialog dialog = ((AppInfoBase) getTargetFragment()).createDialog(id, errorCode); 234 if (dialog == null) { 235 throw new IllegalArgumentException("unknown id " + id); 236 } 237 return dialog; 238 } 239 240 public static MyAlertDialogFragment newInstance(int id, int errorCode) { 241 MyAlertDialogFragment dialogFragment = new MyAlertDialogFragment(); 242 Bundle args = new Bundle(); 243 args.putInt("id", id); 244 args.putInt("moveError", errorCode); 245 dialogFragment.setArguments(args); 246 return dialogFragment; 247 } 248 } 249 } 250