content: package top.niunaijun.blackbox.core.system.pm;
  
  import android.os.Parcel;
  import android.os.Parcelable;
  import android.util.AtomicFile;
  
  import java.io.FileOutputStream;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  
  import top.niunaijun.blackbox.core.env.BEnvironment;
  import top.niunaijun.blackbox.core.system.user.BUserHandle;
  import top.niunaijun.blackbox.entity.pm.InstallOption;
  import top.niunaijun.blackbox.utils.CloseUtils;
  import top.niunaijun.blackbox.utils.FileUtils;
  
  /**
   * updated by alex5402 on 4/21/21.
   * * ∧＿∧
   * (`･ω･∥
   * 丶　つ０
   * しーＪ
   * TFNQw5HgWUS33Ke1eNmSFTwoQySGU7XNsK (USDT TRC20)
   */
  public class BPackageSettings implements Parcelable {
      public BPackage pkg;
      public int appId;
      public InstallOption installOption;
      public Map<Integer, BPackageUserState> userState = new HashMap<>();
      static final BPackageUserState DEFAULT_USER_STATE = new BPackageUserState();
  
      public BPackageSettings() {
      }
  
      public List<BPackageUserState> getUserState() {
          return new ArrayList<>(userState.values());
      }
  
      public List<Integer> getUserIds() {
          return new ArrayList<>(userState.keySet());
      }
  
      public void setInstalled(boolean inst, int userId) {
          modifyUserState(userId).installed = inst;
      }
  
      public boolean getInstalled(int userId) {
          return readUserState(userId).installed;
      }
  
      public boolean getStopped(int userId) {
          return readUserState(userId).stopped;
      }
  
      public void setStopped(boolean stop, int userId) {
          modifyUserState(userId).stopped = stop;
      }
  
      public boolean getHidden(int userId) {
          return readUserState(userId).hidden;
      }
  
      public void setHidden(boolean hidden, int userId) {
          modifyUserState(userId).hidden = hidden;
      }
  
      public void removeUser(int userId) {
          userState.remove(userId);
      }
  
      public BPackageUserState readUserState(int userId) {
          BPackageUserState state = userState.get(userId);
          if (state == null) {
              state = new BPackageUserState();
          }
          state = new BPackageUserState(state);
          // xp模块所有用户可见、如果开启的话
          if (installOption.isFlag(InstallOption.FLAG_XPOSED) &&
                  BXposedManagerService.get().isModuleEnable(pkg.packageName) &&
                  BXposedManagerService.get().isXPEnable()) {
              state.installed = true;
          }
          if (userId == BUserHandle.USER_ALL) {
              state.installed = true;
          }
          return state;
      }
  
      private BPackageUserState modifyUserState(int userId) {
          BPackageUserState state = userState.get(userId);
          if (state == null) {
              state = new BPackageUserState();
              userState.put(userId, state);
          }
          return state;
      }
  
      public boolean save() {
          synchronized (this) {
              Parcel parcel = Parcel.obtain();
              AtomicFile atomicFile = new AtomicFile(BEnvironment.getPackageConf(pkg.packageName));
              FileOutputStream fileOutputStream = null;
              try {
                  writeToParcel(parcel, 0);
                  parcel.setDataPosition(0);
                  fileOutputStream = atomicFile.startWrite();
                  FileUtils.writeParcelToOutput(parcel, fileOutputStream);
                  atomicFile.finishWrite(fileOutputStream);
                  return true;
              } catch (Throwable e) {
                  e.printStackTrace();
                  atomicFile.failWrite(fileOutputStream);
                  return false;
              } finally {
                  parcel.recycle();
                  CloseUtils.close(fileOutputStream);
              }
          }
      }
  
      @Override
      public int describeContents() {
          return 0;
      }
  
      @Override
      public void writeToParcel(Parcel dest, int flags) {
          dest.writeParcelable(this.pkg, flags);
          dest.writeInt(this.appId);
          dest.writeParcelable(this.installOption, flags);
          dest.writeInt(this.userState.size());
          for (Map.Entry<Integer, BPackageUserState> entry : this.userState.entrySet()) {
              dest.writeValue(entry.getKey());
              dest.writeParcelable(entry.getValue(), flags);
          }
      }
  
      protected BPackageSettings(Parcel in) {
          this.pkg = in.readParcelable(BPackage.class.getClassLoader());
          this.appId = in.readInt();
          this.installOption = in.readParcelable(InstallOption.class.getClassLoader());
          int userStateSize = in.readInt();
          this.userState = new HashMap<Integer, BPackageUserState>(userStateSize);
          for (int i = 0; i < userStateSize; i++) {
              Integer key = (Integer) in.readValue(Integer.class.getClassLoader());
              BPackageUserState value = in.readParcelable(BPackageUserState.class.getClassLoader());
              this.userState.put(key, value);
          }
      }
  
      public static final Creator<BPackageSettings> CREATOR = new Creator<BPackageSettings>() {
          @Override
          public BPackageSettings createFromParcel(Parcel source) {
              return new BPackageSettings(source);
          }
  
          @Override
          public BPackageSettings[] newArray(int size) {
              return new BPackageSettings[size];
          }
      };
  }
  